【发布时间】:2017-09-10 07:06:55
【问题描述】:
过去几天我一直在研究这个主题,但没有找到适合我的应用程序的答案。我正在使用 PyQt4 在 python 2.7 中构建一个 GUI 来与机器人交互。我需要一个线程(主线程)来运行使用 QT Designer 创建的 GUI,另一个线程(工作线程)来不断地与机器人之间传输数据。我想在无限工作线程中使用在 GUI(主线程)中输入的数据。在我看过的所有教程中,数据只是从工作线程发送到主线程;就像通常的“加载栏”示例一样。
这是我目前所拥有的。该程序从 QT Designer 导入 GUI 输出,并在按下时将值打印到控制台。我还设置了一个无限线程,可以将“hello”打印到确实可以工作的控制台。只是为了让我指出正确的方向,当单击名为“pushbutton”的按钮时,您能告诉我如何将无限打印“hello”更改为其他内容吗?我熟悉 C/C++,但这是我的第一个 Python 项目,感谢任何帮助。
from PyQt4 import QtGui, QtTest, QtCore # Import the PyQt4 module we'll need
import sys # We need sys so that we can pass argv to QApplication
import gui # Import the GUI output from QT Designer
class GUI(QtGui.QMainWindow, gui.Ui_MainWindow): # This class is to interact with the GUI
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start() # start thread class
######### Binds GUI widgets with functions #####
self.connectbutton.clicked.connect(self.pushbutton) # Call function "pushbutton" when pressed
self.motor_up.clicked.connect(self.motorup) # Call function motorup when pressed
self.motor_down.clicked.connect(self.motordown) # Call function motorup when pressed
self.motor_speed_slider.valueChanged.connect(self.slider) # Call function slider
self.auto_manual_check.stateChanged.connect(self.checkbox) # Call function checkbox
self.Kp_box.valueChanged.connect(self.kp_entry)
self.Ki_box.valueChanged.connect(self.ki_entry)
self.Kd_box.valueChanged.connect(self.kd_entry)
######### Functions to run when GUI event is encountered
def pushbutton(self): # stuff to do if connect button is pressed ## THIS BUTTON
self.connectlabel.setText("Connected")
QtTest.QTest.qWait(2000)
self.connectlabel.setText("Disconnected")
self.emit(SIGNAL("text(Qstring)"),"it worked")
def slider(self): # Stuff to do when slider is changed
print(self.motor_speed_slider.value()) # Print to monitor
def motorup(self): # Run if motor up is clicked
print("motor up")
def motordown(self): # Run if motor down is clicked
print("motor down")
def checkbox(self): # Run if checkbox is changed
if self.auto_manual_check.isChecked():
print("is checked")
else:
print("unchecked")
def kp_entry(self): # Run if kp is changed
print(self.Kp_box.value())
def ki_entry(self): # Run if ki is changed
print(self.Ki_box.value())
def kd_entry(self):# Run if kd is changed
print(self.Kd_box.value())
class ThreadClass(QtCore.QThread): # Infinite thread to communicate with robot
def __init__(self, parent = None):
super(ThreadClass, self).__init__(parent)
def run(self):
while 1: # Runs continuously
print "hello" # CHANGE THIS WHEN pushbutton IS PRESSED
def main(): # Function to run the main GUI
app = QtGui.QApplication(sys.argv) # A new instance of QApplication
form = GUI() # We set the form to be our ExampleApp
form.show() # Show the form
app.exec_() # and execute the app
if __name__ == '__main__': # if we're running file directly and not importing it
main() # run the main function
编辑: 感谢您的快速和详细的答复。在尝试了您的解决方案后,我想我越来越接近了,但是我没有让它们为我的应用程序工作,我想我最初的问题可能不清楚。我本质上是在尝试在线程之间传递变量,实际打印只是为了表明变量已成功传输。我认为这个精简的代码会清除它。
from PyQt4 import QtGui, QtTest, QtCore # Import the PyQt4 module we'll need
import sys # We need sys so that we can pass argv to QApplication
import gui # Import the GUI output from QT Designer
class GUI(QtGui.QMainWindow, gui.Ui_MainWindow): # This class is to interact with the GUI
def __init__(self):
super(self.__class__, self).__init__()
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start()
self.Kp_box.valueChanged.connect(self.kp_entry) # Call function kp_entry if box value is changed
def kp_entry(self): # Run if kp is changed
print(self.Kp_box.value()) # I WANT TO SEND THE BOX VALUE TO THE WORKER THREAD
class ThreadClass(QtCore.QThread): # Infinite thread to communicate with robot
def __init__(self, parent = None):
super(ThreadClass, self).__init__(parent)
def run(self):
while 1:
print self.Kp_box.value() #CONTINUOUSLY PRINT THE UPDATED BOX VALUE
def main(): # Run the main GUI
app = QtGui.QApplication(sys.argv) # A new instance of QApplication
form = GUI() # We set the form to be our ExampleApp
form.show() # Show the form
app.exec_() # and execute the app
if __name__ == '__main__': # if we're running file directly and not importing it
main() # run the main function
我要做的就是让用户在 GUI 中更新一个值,然后将该值传递给工作线程。在这种情况下,我有一个输入框,因此用户可以更改数字。然后我需要程序将该数字传输到将与机器人通信的工作线程。现在代码不起作用,我只是尽可能接近它以更好地展示我正在尝试做的事情。
如果有帮助,这是我的 GUIhere
【问题讨论】:
-
this 答案的 cmets 可能很有用(有一个解释了如何扩展信号/插槽连接以包含其他参数,以便将它们发送给工作人员)。
标签: python multithreading user-interface pyqt4 qt-designer