问题
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()
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
Which is shown the moment I run my
main.py
file, whereas I should get this only and only if I presscommandLinkButton
and should update variables if I update them on my GUI which is not happening.
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:
..............
..............
..............
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?
回答1:
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()
来源:https://stackoverflow.com/questions/46781548/updating-variable-values-when-running-a-thread-using-qthread-in-pyqt4