简体   繁体   English

在PyQt4中使用QThread运行线程时更新变量值

[英]Updating variable values when running a thread using QThread in PyQt4

So problem occurred when I tried using Threading in my code. 因此,当我尝试在代码中使用Threading时发生了问题。 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. 我想做的是将默认值传递给def __init__ ,然后使用具有更新值的实例调用线程,但是以某种方式我无法获取更新值。

Below is my initial code: main.py 下面是我的初始代码: 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()

Below is what I tried: 以下是我尝试的方法:

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

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()
...........................
...........................
...........................

Result: Username Password 结果: Username Password

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. 在运行main.py文件的那一刻就会显示main.py ,而只有在按下commandLinkButton情况下,才应获取此文件;如果在GUI上未进行更新,则应更新变量。

EDIT: 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: 编辑:下面是我再次尝试的方法,如果我在GUI上更新它们,则显示正确的输出,但在这种情况下线程无法正常工作:

..............
..............
..............
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? 所以任何人都可以告诉我该如何处理?

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. 但是请注意,您不得在主线程之外执行任何类型的gui操作 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. 它所能做的就是执行一个冗长的non-gui进程,并在完成后将结果发送回主线程。

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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM