Уведомления

Группа в Telegram: @pythonsu
  • Начало
  • » GUI
  • » Что за фигня творится с потоками в PySide? [RSS Feed]

#1 Май 11, 2012 15:41:26

iroln
От:
Зарегистрирован: 2010-11-22
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Что за фигня творится с потоками в PySide?

Всем привет!

Существует класс, наследуемый от QThread. Существуют два виджета, которые используют экземпляр этого класса. Скажем, виджета 2, экземпляров потока тоже 2. Оба виджета являются детьми главного виджета (главная форма программы). Проблема в том, что метод start одного экземпляра класса потока вызывает метод run другого экземпляра класса потока. Я не могу понять, почему это происходит, в C++ Qt всё в порядке.

Вот минимальный рабочий нерабочий пример:

#coding=utf-8
from PySide import QtCore, QtGui
class MyThread(QtCore.QThread):
    
    def __init__(self, parent=None):
        super(MyThread, self).__init__(parent)
        self.data = 0
        self.mutex = QtCore.QMutex()
        pass
    
    def setData(self, value):
        self.mutex.lock()
        self.data = value
        self.mutex.unlock()
        pass
    
    def getData(self):
        self.mutex.lock()
        value = self.data 
        self.mutex.unlock()
        return value
    
    def run(self):
        self.setData(10)
        
        print 'runned thread obj: {}'.format(self.objectName())
        
        while True:
            if self.getData() < 0:
                break
            
            print 'thread obj {} data: {}'.format(self.objectName(), self.getData())
            self.msleep(1000)
            
            self.setData(self.getData()-1)
        
        print 'thread finished'
        pass
    
    pass
class TestWidget(QtGui.QWidget):
    
    def __init__(self, parent=None):
        super(TestWidget, self).__init__(parent)
        
        self.thread = MyThread()
        
        self.btnStartThread = QtGui.QPushButton('Start thread', self)
        self.btnStartThread.clicked.connect(self.onStart)
        
        self.btnStopThread = QtGui.QPushButton('Stop thread', self)
        self.btnStopThread.clicked.connect(self.onStop)
        
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.btnStartThread)
        layout.addWidget(self.btnStopThread)
        
        self.setLayout(layout)
        pass
    
    @QtCore.Slot()
    def onStart(self):
        if not self.thread.isRunning():
            print 'on start {}'.format(self.objectName())
            print 'started thread obj: {}'.format(self.thread.objectName())
            
            self.thread.start()
        pass
    
    @QtCore.Slot()
    def onStop(self):
        print 'on stop {}'.format(self.objectName())
        print 'stopped thread obj: {}'.format(self.thread.objectName())
        self.thread.setData(-1)
        pass
    
    pass
#################################
if __name__ == '__main__':
    import sys
    
    app = QtGui.QApplication(sys.argv)
    
    main_widget = QtGui.QWidget()
    
    test_widget1 = TestWidget(main_widget)
    test_widget2 = TestWidget(main_widget)
    
    test_widget1.setObjectName('TestWidget1')
    test_widget2.setObjectName('TestWidget2')
    
    test_widget1.thread.setObjectName('Thread1')
    test_widget2.thread.setObjectName('Thread2')
    
    layout = QtGui.QHBoxLayout()
    layout.addWidget(test_widget1)
    layout.addWidget(test_widget2)
    
    main_widget.setLayout(layout)
    main_widget.show()
    
    sys.exit(app.exec_())
    pass

При клике на кнопку start виджета TestWidget1 стартует поток Thread2. То есть метод start одного экземпляра запускает поток второго экземпляра.

Что происходит вообще, кто-нибудь знает? Может я что-то не так делаю?



Отредактировано iroln (Май 11, 2012 19:36:14)

Офлайн

#2 Май 11, 2012 16:43:32

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Что за фигня творится с потоками в PySide?

По-моему все нормально:

on start TestWidget1
started thread obj: Thread1
runned thread obj: Thread1
thread obj Thread1 data: 10
thread obj Thread1 data: 9
on stop TestWidget1
...
on start TestWidget2
started thread obj: Thread2
runned thread obj: Thread2
thread obj Thread2 data: 10
on stop TestWidget2
stopped thread obj: Thread2
thread finished

Может дело в версиях Python, OS и PySide (хотя маловероятно)?
Еще в PyQt можно попробовать, если установлен.

Отредактировано reclosedev (Май 11, 2012 16:47:08)

Офлайн

#3 Май 11, 2012 17:40:55

iroln
От:
Зарегистрирован: 2010-11-22
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Что за фигня творится с потоками в PySide?

Я использую PySide 1.0.9 x64 py27 на win7 так как у 1.1.0 были проблемы при работе в бинарной сборке. Я еще проверю в другом окружении и так же с PyQt4. Но поведение очень странное.

UPD:
Проверил в другом окружении с разными версиями PySide, всё правильно работает. Видимо что-то поломалось в моём рабочем окружении, буду разбираться.



Отредактировано iroln (Май 11, 2012 19:53:58)

Офлайн

#4 Май 11, 2012 20:11:51

reclosedev
От: Н.Новгород
Зарегистрирован: 2012-03-29
Сообщения: 870
Репутация: +  173  -
Профиль   Отправить e-mail  

Что за фигня творится с потоками в PySide?

iroln
Проверил в другом окружении с разными версиями PySide, всё правильно работает. Видимо что-то поломалось в моём рабочем окружении, буду разбираться.
У меня есть предположение, что дело в *.pyc файлах, которые могли остаться. Бывает, что они исполняются вместо py. Не помню в каких случаях, но у меня бывало такое (вроде с переименованием связано было). Попробуйте почистить.

Офлайн

#5 Май 14, 2012 08:00:37

iroln
От:
Зарегистрирован: 2010-11-22
Сообщения: 13
Репутация: +  0  -
Профиль   Отправить e-mail  

Что за фигня творится с потоками в PySide?

Проблема с отладчиком в WingIDE 4.1.5-1



Офлайн

  • Начало
  • » GUI
  • » Что за фигня творится с потоками в PySide?[RSS Feed]

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version