Форум сайта python.su
Всем привет!
Существует класс, наследуемый от 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
Отредактировано iroln (Май 11, 2012 19:36:14)
Офлайн
По-моему все нормально:
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
Отредактировано reclosedev (Май 11, 2012 16:47:08)
Офлайн
Я использую PySide 1.0.9 x64 py27 на win7 так как у 1.1.0 были проблемы при работе в бинарной сборке. Я еще проверю в другом окружении и так же с PyQt4. Но поведение очень странное.
UPD:
Проверил в другом окружении с разными версиями PySide, всё правильно работает. Видимо что-то поломалось в моём рабочем окружении, буду разбираться.
Отредактировано iroln (Май 11, 2012 19:53:58)
Офлайн
irolnУ меня есть предположение, что дело в *.pyc файлах, которые могли остаться. Бывает, что они исполняются вместо py. Не помню в каких случаях, но у меня бывало такое (вроде с переименованием связано было). Попробуйте почистить.
Проверил в другом окружении с разными версиями PySide, всё правильно работает. Видимо что-то поломалось в моём рабочем окружении, буду разбираться.
Офлайн
Проблема с отладчиком в WingIDE 4.1.5-1
Офлайн