Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/visual-studio/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用QThreads的正确方法是什么?_Python_Multithreading_Pyside_Qthread - Fatal编程技术网

Python 使用QThreads的正确方法是什么?

Python 使用QThreads的正确方法是什么?,python,multithreading,pyside,qthread,Python,Multithreading,Pyside,Qthread,我正在尝试使用PySide构建一个具有多个窗口的Python应用程序。每个窗口执行一些函数,一个函数的执行不应该阻止其他窗口执行它们自己的函数,这就是为什么我需要使用多线程。但是我不知道怎么做。我尝试使用新方法来使用线程(正确的一个),但是我在网上找到的所有例子都是C++的,我对C++一无所知,这就是我请求帮助的原因。 为了简化起见,我构建了两个模块,一个名为test\u main,另一个名为test\u wdw 这是test\u main的代码: import sys import test_

我正在尝试使用PySide构建一个具有多个窗口的Python应用程序。每个窗口执行一些函数,一个函数的执行不应该阻止其他窗口执行它们自己的函数,这就是为什么我需要使用多线程。但是我不知道怎么做。我尝试使用新方法来使用线程(正确的一个),但是我在网上找到的所有例子都是C++的,我对C++一无所知,这就是我请求帮助的原因。 为了简化起见,我构建了两个模块,一个名为
test\u main
,另一个名为
test\u wdw

这是
test\u 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()
这是测试的代码:

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\u operation()
函数

我试图添加
操作。在
test\u wdw
文件的末尾运行
,但实际情况是
run\u operation()
在运行应用程序后立即开始执行,并且根本没有显示GUI

添加
操作。在启动窗口函数中运行\u操作()
刚刚使GUI崩溃

这让我意识到,
run\u操作
函数并没有像预期的那样在单独的线程中运行

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

我想解释一下信号和插槽在
QThread
上下文中的作用,以及它们是如何使用的,我想对我发布的代码进行更正,使其按预期运行

其他信息:

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

  • <> UL>

    在对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()
    
    测试的正确代码为:

    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)
    
    从PySide导入QtGui
    从PySide导入QtCore
    def启动_窗口():
    全局窗口
    #创建一个新窗口
    window=QtGui.QWidget()
    setAttribute(QtCore.Qt.WA_DeleteOnClose)
    window.setWindowTitle(“窗口1”)
    #为窗口创建布局并使用Qlabel填充它
    window.grid=QtGui.QGridLayout()
    window.label=QtGui.QLabel(“你好”)
    window.grid.addWidget(window.label,0,0)
    #设置窗口的布局并设置窗口的大小
    window.setLayout(window.grid)
    window.setFixedSize(window.sizeHint())
    #开始线程
    myThread.start()
    类运行_操作(QtCore.QObject):
    #为操作结束时创建QtCore信号(如果您希望函数结束处理时发生某些事情)
    完成\u操作=QtCore.Signal()
    #包装要在QtCore插槽中运行的函数(必需!)
    @QtCore.Slot()
    #我想在一个单独的线程中运行的函数!现在它跑了!
    def run_操作(自):
    全局计数器
    计数器=0
    #设置每秒触发的计时器,同时调用函数print_counter()
    全局计时器
    定时器=QtCore.QTimer(自身)
    定时器.超时.连接(自打印计数器)
    定时器启动(1000)
    def打印计数器(自身):
    全局计数器
    全局计时器
    #一个仅用于测试目的的随机函数,计数器每秒都在计数。
    如果计数器