TransWikia.com

PyQT. Почему не работает show() в потоке?

Stack Overflow на русском Asked by zEvilCube on March 3, 2021

Если showLabel() используется вне потока, то всё работает.
Если я пытаюсь поместить showLabel() в поток, то программа зависает и вылетает именно на строке self.label.show().

В чём может быть проблема и как это можно решить?

Код (очень сокращён):

import sys
from threading import *
from PyQt5.QtWidgets import *


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Window')
        self.setGeometry(300, 300, 500, 500)

    def showLabel(self):
        self.label = QLabel('Label', self)
        self.label.move(100, 100)
        self.label.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    showLabel()  # Без потока 
    Thread(target=window.showLabel).start()  # С потоком
    sys.exit(app.exec())

2 Answers

Элементы графического интерфейса (все, что унаследовано или связано с подклассом QWidget) должны быть созданы и доступны только из основного потока Qt.

import sys
#from threading import *
from PyQt5.Qt import *


class Thread(QThread):
    dataThread = pyqtSignal(str)
    
    def __init__(self):
        QThread.__init__(self)
        self.number = 1

    def run(self):
        for i in range(20):
            self.dataThread.emit(f"Label {self.number}")
            self.number += 1
            self.msleep(1000)


class Window(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        self.setWindowTitle('Window')

        self.label = QLabel(self)
        self.label.move(100, 100)
        self.showLabel('Label   ')
        
        self.worker = Thread()
        self.worker.dataThread.connect(self.showLabel)
        self.worker.start() 

    def showLabel(self, text):
        self.label.setText(text)  
        self.label.adjustSize() 


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.resize(500, 500)
    window.show()
    sys.exit(app.exec_())

введите сюда описание изображения

Answered by S. Nick on March 3, 2021

import sys
from threading import *
from PyQt5.QtWidgets import *
from PyQt5.QtCore import pyqtSignal


class Window(QWidget):
    signal = pyqtSignal()

    def __init__(self):
        super().__init__()
        self.initUI()
        self.signal.connect(self.showLabel)  
 
    def initUI(self):
        self.setWindowTitle('Window')
        self.setGeometry(300, 300, 500, 500)

    def showLabel(self):
        self.label = QLabel('Label', self)
        self.label.move(100, 100)
        self.label.show()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    window = Window()
    window.show()
    window.showLabel()  # Без потока 
    Thread(target=window.signal.emit).start()  # С потоком
    sys.exit(app.exec())

Answered by Victor VosMottor on March 3, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP