运行 线程在 PyQt4 中使用 QThread 时更新变量值
Updating variable values when running a thread using QThread in PyQt4
所以当我尝试在我的代码中使用 Threading
时出现了问题。我想要做的是将默认值传递给 def __init__
,然后使用更新值的实例调用线程,但不知何故我无法获得更新值。
下面是我的初始值代码: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()
...........................
...........................
...........................
结果: 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.
编辑: 下面是我再次尝试的,如果我在 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()
......................
......................
......................
所以有人可以告诉我如何处理这个问题吗?
您需要使用自定义信号将身份验证结果发送回主线程。但请注意,您不得在主线程外执行任何类型的任何 gui 操作。因此,例如,工作线程无法显示身份验证对话框或尝试直接更新小部件。它所能做的就是执行一个冗长的非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):
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()
所以当我尝试在我的代码中使用 Threading
时出现了问题。我想要做的是将默认值传递给 def __init__
,然后使用更新值的实例调用线程,但不知何故我无法获得更新值。
下面是我的初始值代码: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()
...........................
...........................
...........................
结果: 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.
编辑: 下面是我再次尝试的,如果我在 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()
......................
......................
......................
所以有人可以告诉我如何处理这个问题吗?
您需要使用自定义信号将身份验证结果发送回主线程。但请注意,您不得在主线程外执行任何类型的任何 gui 操作。因此,例如,工作线程无法显示身份验证对话框或尝试直接更新小部件。它所能做的就是执行一个冗长的非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):
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()