Найти - Пользователи
Полная версия: Что за фигня творится с потоками в PySide?
Начало » GUI » Что за фигня творится с потоками в PySide?
1
iroln
Всем привет!

Существует класс, наследуемый от 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 одного экземпляра запускает поток второго экземпляра.

Что происходит вообще, кто-нибудь знает? Может я что-то не так делаю?
reclosedev
По-моему все нормально:
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 можно попробовать, если установлен.
iroln
Я использую PySide 1.0.9 x64 py27 на win7 так как у 1.1.0 были проблемы при работе в бинарной сборке. Я еще проверю в другом окружении и так же с PyQt4. Но поведение очень странное.

UPD:
Проверил в другом окружении с разными версиями PySide, всё правильно работает. Видимо что-то поломалось в моём рабочем окружении, буду разбираться.
reclosedev
iroln
Проверил в другом окружении с разными версиями PySide, всё правильно работает. Видимо что-то поломалось в моём рабочем окружении, буду разбираться.
У меня есть предположение, что дело в *.pyc файлах, которые могли остаться. Бывает, что они исполняются вместо py. Не помню в каких случаях, но у меня бывало такое (вроде с переименованием связано было). Попробуйте почистить.
iroln
Проблема с отладчиком в WingIDE 4.1.5-1
This is a "lo-fi" version of our main content. To view the full version with more information, formatting and images, please click here.
Powered by DjangoBB