PyQt5多线程防卡死和多窗口用法的实现

  

为了实现PyQt5多线程防卡死和多窗口用法,您可以遵循以下步骤:

1. 多线程防卡死

在PyQt5中,当涉及到大量数据处理时,可能会导致GUI线程被阻塞,从而导致应用程序出现卡顿或崩溃的情况。为了防止这种情况的发生,可以使用多线程来处理数据。

以下是多线程防卡死的实现方法:

from PyQt5.QtCore import QThread, pyqtSignal

class Worker(QThread):
    finish_signal = pyqtSignal()

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

    def run(self):
        # Add your long running code here
        self.finish_signal.emit()
  • 创建一个Worker类,继承于QThread
  • Worker类的构造函数中初始化参数
  • run()方法中添加长时间运行的代码
  • 发出finish_signal信号,在run()方法执行完后发出信号

如上代码展示,定义了一个Worker线程类。Worker继承自QThread,因此可以在其中使用.start()方法启动线程。run()方法中添加了需要被执行的长时间运行的代码。当处理完数据并运行完后,发出了finish_signal信号。

2. 多窗口用法

在PyQt5中,可以使用多个窗口来构建多个模块的UI界面,以及使应用程序更加用户友好。

以下是多窗口用法的实现方法:

from PyQt5.QtWidgets import QApplication, QMainWindow

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.second_window = SecondWindow(self)
        self.initUI()

    def initUI(self):
        # Add your code to create the main window
        self.second_window.show()

class SecondWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        # Add your code to create the second window
  • 创建QMainWindow
  • 在主窗口内创建第二个窗口
  • 添加代码创建主窗口
  • 在主窗口内添加代码显示第二个窗口
  • 创建第二个窗口(QMainWindow)

如上代码展示,首先创建MainWindow类,然后在其中创建第二个窗口SecondWindow。在MainWindow类中添加代码以创建主窗口和触发第二个窗口的显示。在SecondWindow类中创建第二个窗口。需要注意的是,第二个窗口也需要继承自QMainWindow

示例说明:

  1. 实现多线程防卡死

在以下示例中,网络I/O操作被放置于另一个线程中,以防止阻塞GUI线程并使应用程序卡顿或崩溃。

from PyQt5.QtCore import QThread, pyqtSignal, pyqtSlot
from PyQt5.QtWidgets import QApplication, QPushButton, QVBoxLayout, QWidget
import requests

class Worker(QThread):
    finish_signal = pyqtSignal()

    def __init__(self, url):
        super().__init__()
        self.url = url

    @pyqtSlot()
    def run(self):
        try:
            response = requests.get(self.url)
            status_code = response.status_code
            content_type = response.headers['Content-Type']
        except:
            status_code = 'error'
            content_type = 'error'
        finally:
            print(f'Status Code: {status_code}')
            print(f'Content Type: {content_type}')
            self.finish_signal.emit()

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

    def initUI(self):
        self.btn = QPushButton('Get Data', self)
        self.btn.clicked.connect(self.getData)
        layout = QVBoxLayout(self)
        layout.addWidget(self.btn)
        self.worker = Worker('https://jsonplaceholder.typicode.com/posts/1')
        self.worker.finish_signal.connect(self.finished)
        self.show()

    @pyqtSlot()
    def finished(self):
        print('Worker thread finished')

    @pyqtSlot()
    def getData(self):
        self.worker.start()

if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    app.exec_()
  • 定义了一个Worker类,其继承自QThread,并在run()方法内添加了长时间运行的网络I/O操作。
  • MainWindow类中创建了一个QPushButton,并将其连接到一个getData()方法上,该方法会触发worker线程的启动。
  • worker线程完成时,finished()方法会被调用,worker线程的信号也会传递到MainWindow对象中。

  • 实现多窗口用法

以下示例展示了如何创建多个窗口并使之彼此关联。

from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton, QVBoxLayout, QWidget

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.second_window = SecondWindow(self)
        self.initUI()

    def initUI(self):
        btn = QPushButton('Click me', self)
        btn.clicked.connect(self.clickHandler)
        layout = QVBoxLayout(self)
        layout.addWidget(btn)
        self.show()

    def clickHandler(self):
        self.second_window.show()

class SecondWindow(QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.initUI()

    def initUI(self):
        btn = QPushButton('Close me', self)
        btn.clicked.connect(self.close)
        layout = QVBoxLayout(self)
        layout.addWidget(btn)

if __name__ == '__main__':
    app = QApplication([])
    window = MainWindow()
    app.exec_()
  • 我们首先创建了MainWindow类,然后在其中创建了一个SecondWindow实例,并将主窗口对象的引用传递给其构造函数。
  • MainWindow对象的初始化方法中,我们创建了一个按钮,并将该按钮与clickHandler()函数连接,该函数会打开SecondWindow窗口。
  • SecondWindow类中创建了一个按钮,并将其与close()函数连接,该函数用于关闭当前窗口。

当主窗口中的按钮被点击后,SecondWindow窗口就会被打开,然后可以通过按钮关闭该窗口以返回到主窗口。

相关文章