在 PyQt4 中使用 QThread 运行线程时更新变量值 [英] Updating variable values when running a thread using QThread in PyQt4

查看:57
本文介绍了在 PyQt4 中使用 QThread 运行线程时更新变量值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当我尝试在我的代码中使用 Threading 时出现问题.我想要做的是将默认值传递给 def __init__,然后使用其实例调用线程并使用更新的值但不知何故我无法获得更新的值.

下面是我的初始值代码:ma​​in.py

So problem occurred when I tried using Threading in my code. What I want to do is passing default values to the def __init__ and then calling the thread with its instance with updated values but somehow I cannot get the updated values.

Below is my initial code: main.py

from PyQt4 import QtGui
import sys
import GUI # GUI app by using PYQT4
from PyQt4.QtCore import QThread
#import Photos

class PyMain(QtGui.QWidget, GUI.Ui_Pycloud):
    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.password.setEchoMode(QtGui.QLineEdit.Password)

        """Picking up data from GUI.py file where initially,
        it is set to 'Username' and 'Password' respectively.
        and initialising `GetThread` class"""
        self.get_thread = GetThread(str(self.username.text()), 
                                    str(self.password.text())
                                   )
        """This is what I was initially using.
           I have tried, only passing the instance and calling 
           get_thread.start() inside __init__ fn but even if i don't click 
           `commandLinkButton` it is somehow called automatically.
           I know it is not the right approach"""
        self.commandLinkButton.clicked.connect(self.get_thread.start)


class GetThread(QThread):

    def __init__(self, username, password):
        QThread.__init__(self)
        self.username = username
        self.password = password

    def __del__(self):
        self.wait()

    def authentication(self):
        print self.username, self.password
        # user = Photos.PyPhotos(self.username, self.password)
        # user.authentication(user)

    def run(self):
        self.authentication()


def main():
    app = QtGui.QApplication(sys.argv)
    form = PyMain()
    form.show()
    app.exec_()

if __name__ == '__main__':
    main()

以下是我尝试过的:

...........................
...........................
...........................

class PyMain(QtGui.QWidget, GUI.Ui_Pycloud):
  def __init__(self):
    super(self.__class__, self).__init__()
    self.setupUi(self)
    self.password.setEchoMode(QtGui.QLineEdit.Password)
    self.commandLinkButton.clicked.connect(GetThread(str(self.username.text()), 
                                             str(self.password.text())).__init__)

class GetThread(QThread):

 def __init__(self, username, password):
        QThread.__init__(self)
        self.username = username
        self.password = password
        self.start()
...........................
...........................
...........................

结果: 用户名密码

在我运行我的 main.py 文件时显示的内容,而我应该只在我按下 commandLinkBut​​ton 时才应该得到这个,并且如果我更新它们应该更新变量在我的 GUI 上没有发生.

Which is shown the moment I run my main.py file, whereas I should get this only and only if I press commandLinkButton and should update variables if I update them on my GUI which is not happening.

以下是我再次尝试的内容,如果我在 GUI 上更新它们,它会向我显示正确的输出,但在这种情况下线程不起作用:

Below is what I tried again, it is showing me the correct output if I update them on GUI but threading is not working in this case:

..............
..............
..............
class PyMain(QtGui.QWidget, GUI.Ui_Pycloud):
    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.password.setEchoMode(QtGui.QLineEdit.Password)
        self.commandLinkButton.clicked.connect(self.populate)

    def populate(self):
        get_thread = GetThread(str(self.username.text()), str(self.password.text()))
        get_thread.start()


class GetThread(QThread):

    def __init__(self, username, password):
        QThread.__init__(self)
        self.username = username
        self.password = password

    def __del__(self):
        self.wait()

    def authentication(self):
        print self.username, self.password
        user = Photos.PyPhotos(self.username, self.password)
        user.authentication(user)

    def run(self):
        self.authentication()
......................
......................
......................

所以任何人都可以告诉我如何解决这个问题?

So anyone can please tell me how to approach this?

推荐答案

您需要使用自定义信号将认证结果发送回主线程.但请注意,不得在主线程之外执行任何类型的 gui 操作.因此,例如,工作线程无法显示身份验证对话框或尝试直接更新小部件.它所能做的就是执行一个冗长的非 gui 进程,并在完成后将结果发送回主线程.

You need to use a custom signal to send the authentication result back the main thread. But note that you must not perform any gui operations of any kind outside the main thread. So, for example, the worker thread cannot show an authentication dialog or attempt to directly update widgets. All it can do is execute a lengthy non-gui process and send the result back to the main thread when it's finished.

代码的基本结构应该是这样的:

The basic structure of the code should look like this:

class PyMain(QtGui.QWidget, GUI.Ui_Pycloud):
    def __init__(self):
        super(self.__class__, self).__init__()
        self.setupUi(self)
        self.password.setEchoMode(QtGui.QLineEdit.Password)
        self.commandLinkButton.clicked.connect(self.populate)

    def populate(self):
        self.thread = GetThread(self.username.text(), self.password.text())
        self.thread.authResult.connect(self.handleAuthResult)
        self.thread.start()

    def handleAuthResult(self, result):
        # do something with result...

class GetThread(QThread):
    authResult = QtCore.pyqtSignal(object)

    def __init__(self, username, password):
        QThread.__init__(self)
        self.username = username
        self.password = password

    def authentication(self):
        result = do_authentication()
        self.authResult.emit(result)

    def run(self):
        self.authentication()

这篇关于在 PyQt4 中使用 QThread 运行线程时更新变量值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆