gpt4 book ai didi

python - 使用 QThread 的正确方法是什么?

转载 作者:行者123 更新时间:2023-12-01 05:28:58 25 4
gpt4 key购买 nike

我正在尝试使用 PySide 在 Python 中构建一个具有多个窗口的应用程序。每个窗口都执行一些函数,并且一个函数的执行不应阻止其他窗口执行自己的函数,这就是我需要使用多线程的原因。但是我不知道该怎么做。我正在尝试使用新方法来使用线程(正确的方法),但我在网上找到的所有示例都是 C++ 语言,而我对 C++ 毫无了解,这就是我寻求帮助的原因。

为了简化起见,我构建了两个模块,一个名为 test_main,另一个名为 test_wdw

这是test_main的代码:

import sys
import test_wdw
from PySide import QtGui
from PySide import QtCore

class Main_Window(QtGui.QMainWindow):
def __init__(self):
super(Main_Window,self).__init__()
self.initUI()

def initUI(self):
self.statusBar()

self.new_window=QtGui.QAction("&Window alpha",self)
self.new_window.triggered.connect(self.open_window)

self.menu_bar=self.menuBar()
self.menu1=self.menu_bar.addMenu('&Menu 1')
self.menu1.addAction(self.new_window)

# Creates a QMdiArea to manage all windows
self.wmanager=QtGui.QMdiArea()
self.setCentralWidget(self.wmanager)

# Shows the main window
self.showMaximized()

def open_window(self):
test_wdw.launch_window()
test_wdw.window_alpha=self.wmanager.addSubWindow(test_wdw.window)
# Shows the new window
test_wdw.window_alpha.show()

def main():
app=QtGui.QApplication(sys.argv)
main_wdw=Main_Window()
sys.exit(app.exec_())

if __name__=="__main__":
main()

这是test_wdw的代码:

from PySide import QtGui
from PySide import QtCore

def launch_window():
global window

window=QtGui.QWidget()
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.setWindowTitle('Window 1')

window.grid=QtGui.QGridLayout()
window.label=QtGui.QLabel("Hello")
window.grid.addWidget(window.label,0,0)

window.setLayout(window.grid)
window.setFixedSize(window.sizeHint())

class running_operation(QtCore.QObject):
# Function I would like to run in a separate thread
def run_operation(self):
while True:
print("hi")


myThread=QtCore.QThread()
operations = running_operation()
operations.moveToThread(myThread)
myThread.start()

我的问题是我不知道从这里该去哪里。我希望一旦新窗口启动,它就会在新线程中启动 run_operation() 函数。

我尝试将 operations.run_operation() 添加到 test_wdw 文件的末尾,但发生的情况是 run_operation() 开始执行运行应用程序后立即没有任何 GUI 显示。

在 launch_window 函数中添加 operations.run_operation() 只会导致 GUI 崩溃。

这让我意识到 run_operation 函数没有按预期在单独的线程中运行。

我继续阅读文档,我相信我需要创建信号和槽才能运行。我知道如何使用信号和槽将 QObject 连接到我希望它们在触发时执行的函数,但我不明白信号和槽与 QThread 有什么关系code> 并且我无法达到预期的结果。

我想解释QThread上下文中信号和槽的作用以及它们的使用方式,并且我想更正我发布的代码,以便它运行为预计。

其他信息:

  • 操作系统:Windows 7 64 位
  • Python 版本:3.3
  • PySide 版本:1.2.1

最佳答案

经过多次尝试、错误以及对一些 C++ 教程的解码,我最终自己找到了解决方案。

test_main 的代码保持不变。

import sys
import test_wdw
from PySide import QtGui
from PySide import QtCore

class Main_Window(QtGui.QMainWindow):
def __init__(self):
super(Main_Window,self).__init__()
self.initUI()

def initUI(self):
self.statusBar()

self.new_window=QtGui.QAction("&Window alpha",self)
self.new_window.triggered.connect(self.open_window)

self.menu_bar=self.menuBar()
self.menu1=self.menu_bar.addMenu('&Menu 1')
self.menu1.addAction(self.new_window)

# Creates a QMdiArea to manage all windows
self.wmanager=QtGui.QMdiArea()
self.setCentralWidget(self.wmanager)

# Shows the main window
self.showMaximized()

def open_window(self):
test_wdw.launch_window()
test_wdw.window_alpha=self.wmanager.addSubWindow(test_wdw.window)
# Shows the new window
test_wdw.window_alpha.show()

def main():
app=QtGui.QApplication(sys.argv)
main_wdw=Main_Window()
sys.exit(app.exec_())

if __name__=="__main__":
main()

test_wdw 的正确代码是:

from PySide import QtGui
from PySide import QtCore

def launch_window():
global window
# Creates a new window
window=QtGui.QWidget()
window.setAttribute(QtCore.Qt.WA_DeleteOnClose)
window.setWindowTitle('Window 1')
# Creates a layout for the window and populates it with a Qlabel
window.grid=QtGui.QGridLayout()
window.label=QtGui.QLabel("Hello")
window.grid.addWidget(window.label,0,0)
# Sets the layout to the window and sets the size of the window
window.setLayout(window.grid)
window.setFixedSize(window.sizeHint())
# Starts the thread
myThread.start()

class running_operation(QtCore.QObject):

# Creates a QtCore Signal for when the operation is over (if you want something to happen when the function ends processing)
finish_operation=QtCore.Signal()
# Wraps the function to run inside a QtCore Slot (MANDATORY !)
@QtCore.Slot()
# Function I wanted to run in a separate thread ! NOW IT RUNS !
def run_operation(self):
global counter
counter=0
# Setting a timer that fires every second and calling at the same time the function print_counter()
global timer
timer=QtCore.QTimer(self)
timer.timeout.connect(self.print_counter)
timer.start(1000)

def print_counter(self):
global counter
global timer
# A random function to execute just for testing purposes, the counter keeps counting up every second.
if counter <= 3 :
counter += 1
print(counter)
elif counter == 4 :
# At seconds, we emit the finish_operation signal.
counter += 1
self.finish_operation.emit()
# At 5 seconds and more, the counter keeps counting up again every second (just to check if the thread actually exited)
else:
counter += 1
print(counter)


# Creates a new thread
myThread=QtCore.QThread()
# Creates the object "operations"
operations = running_operation()
# Moves the object to the thread
operations.moveToThread(myThread)
# Connects the QThread.started signal function to the run_operation() function.
myThread.started.connect(operations.run_operation)
# Connects the finish_operation signal to quitting the thread.
operations.finish_operation.connect(myThread.quit)

我添加到原始帖子(问题)中的所有内容都在代码注释中进行了解释。

我可以看出该函数是在单独的线程中启动的,因为 GUI 没有挂起。

我可以告诉线程正确退出,因为 4 秒后,程序没有在输出中打印任何内容。如果线程没有正确退出,并且由于我构造函数 print_counter() 的方式,程序将在第 4 秒停止打印到输出 1 秒,然后它会第 5 秒再次开始打印到输出。

我希望有些人会发现这很有用,并可以在此基础上继续发展。

关于python - 使用 QThread 的正确方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20741699/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com