簡體   English   中英

在 pyqt5 中使用多個 windows 進行多線程更新

[英]Multithreading updating with multiple windows in pyqt5

我正在嘗試使用一個計時器來更新多個 windows 和 pyqt5 中的值。 到目前為止,我所擁有的主要 window 打開按鈕以打開另一個 windows,但是當我按下任一按鈕時,它會崩潰。

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QLabel, QVBoxLayout, QWidget,  QLineEdit
from PyQt5.QtCore import QRunnable, pyqtSlot, QTimer, QThreadPool
import sys

timer = QTimer()
timer.setInterval(1000) 

timer.start()

class Worker(QRunnable):

    def __init__(self, fn, *args, **kwargs):
        super(Worker, self).__init__()

        self.fn = fn
        self.args = args
        self.kwargs = kwargs

    @pyqtSlot()
    def run(self):

        self.fn(*self.args, **self.kwargs)

class AnotherWindow(QWidget):

    def __init__(self):
        super().__init__()
        self.x = 0
        layout = QVBoxLayout()
        self.label = QLabel("Another Window")
        layout.addWidget(self.label)
        self.line = QLineEdit(self)
        layout.addWidget(self.line)       
        self.setLayout(layout)
        timer.timeout.connect(self.update_line)
        
    def update_line(self):
        self.x += 1
        self.line.setText(str(self.x))

class AnotherWindow2(QWidget):

    def __init__(self):
        super().__init__()
        self.x = 0
        layout = QVBoxLayout()
        self.label = QLabel("Another Window2")
        layout.addWidget(self.label)
        self.line = QLineEdit(self)
        layout.addWidget(self.line)       
        self.setLayout(layout)
        timer.timeout.connect(self.update_line)
        
    def update_line(self):
        self.x += 3
        self.line.setText(str(self.x))
        
class MainWindow(QMainWindow):

    def __init__(self):
        super().__init__()
        l = QVBoxLayout()
        button1 = QPushButton("Push for Window 1")
        button1.clicked.connect(self.show_new_window)
        l.addWidget(button1)

        button2 = QPushButton("Push for Window 2")
        button2.clicked.connect(self.show_new_window2)
        l.addWidget(button2)

        w = QWidget()
        w.setLayout(l)
        self.setCentralWidget(w)

        self.threadpool = QThreadPool()
        print("Multithreading with maximum %d threads" % self.threadpool.maxThreadCount())

    def show_new_window(self):
        worker = Worker(self.open_AnotherWindow)
        self.threadpool.start(worker)
        
    def open_AnotherWindow(self):
        self.w = AnotherWindow()
        self.w.show()

    def show_new_window2(self, checked):
        worker2 = Worker(self.open_AnotherWindow2)
        self.threadpool.start(worker2)
        
    def open_AnotherWindow2(self, checked):
        self.w2 = AnotherWindow2()
        self.w2.show()


app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()

打印出線程數。 我也試過把

        self.timer = QTimer()
        self.timer.setInterval(1000) 
        self.timer.timeout.connect(self.update_line)
        self.timer.start()

在每個另一個窗口(2)中初始化function,但這也會崩潰。 也許計時器應該以某種方式在主窗口中? 雖然它的結果沒有顯示在那里。 我看過關於多線程和多窗口的教程,但沒有看到每個線程都有一個 window 並且所有線程都訪問相同的數據。

為什么需要使用多線程? 線程不是神奇的解決方案,相反,如果不知道它們的缺點,那么它們帶來的問題多於解決方案。 在您的情況下,這是不必要的,因為您沒有任何阻塞 GUI 的耗時任務。 底線:在必要時使用工具,而不是在需要時使用。

另一方面,您正在從 Qt 禁止的另一個線程創建 GUI,因為它不是線程安全的。

class AnotherWindow(QWidget):
    def __init__(self):
        super().__init__()
        self.x = 0
        layout = QVBoxLayout()
        self.label = QLabel("Another Window")
        layout.addWidget(self.label)
        self.line = QLineEdit(self)
        layout.addWidget(self.line)
        self.setLayout(layout)
        timer = QTimer(self)
        timer.timeout.connect(self.update_line)
        timer.start()

    def update_line(self):
        self.x += 1
        self.line.setText(str(self.x))


class AnotherWindow2(QWidget):
    def __init__(self):
        super().__init__()
        self.x = 0
        layout = QVBoxLayout()
        self.label = QLabel("Another Window2")
        layout.addWidget(self.label)
        self.line = QLineEdit(self)
        layout.addWidget(self.line)
        self.setLayout(layout)
        timer = QTimer(self)
        timer.timeout.connect(self.update_line)
        timer.start()

    def update_line(self):
        self.x += 3
        self.line.setText(str(self.x))


class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        l = QVBoxLayout()
        button1 = QPushButton("Push for Window 1")
        button1.clicked.connect(self.show_new_window)
        l.addWidget(button1)

        button2 = QPushButton("Push for Window 2")
        button2.clicked.connect(self.show_new_window2)
        l.addWidget(button2)

        w = QWidget()
        w.setLayout(l)
        self.setCentralWidget(w)

    def show_new_window(self):
        self.w = AnotherWindow()
        self.w.show()

    def show_new_window2(self):
        self.w2 = AnotherWindow2()
        self.w2.show()


app = QApplication(sys.argv)
w = MainWindow()
w.show()
app.exec_()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM