Python程序不断崩溃

时间:2015-03-20 20:47:12

标签: python serial-port pyqt

我正在尝试创建一个简单的UI来控制我是否可以从串口打印数据并使用PyQT,我创建了一个带有两个按钮的简单UI - 一个开始录制按钮和一个停止录制按钮。

按下“开始录制”按钮时,数据将被打印出来,但是当我按下“停止录制”按钮时,系统将挂起并且while循环继续运行。我想这可能是因为程序试图摆脱while循环,但是无法做到。我非常感谢你的帮助。

主要代码:

import gui_main
import sys 
import numpy 
from PyQt4 import QtCore, QtGui
import PyQt4.Qwt5 as Qwt
import matplotlib
import serial 
import threading


global readervar

def reader(): 
    readervar= True

    ser = serial.Serial(7) #insert COM port number from which data is being collected
    ser.baudrate = 9600 #insert baud rate 
    while True: 
        if readervar: 
            line= ser.readline()
            print (line)
            print(readervar)
        else if uiplot.btn2.clicked(): 
            break
    readervar=False


def shutter(): 
    readervar=False

def main(): 
    global uiplot
    app = QtGui.QApplication(sys.argv)
    win_plot = gui_main.QtGui.QMainWindow()
    uiplot = gui_main.Ui_Form()
    uiplot.setupUi(win_plot)

    uiplot.btn1.clicked.connect(reader)
    uiplot.btn2.clicked.connect(shutter)
    # DISPLAY WINDOWS
    win_plot.show()
    code = app.exec_()

    sys.exit(code)



if __name__ == "__main__":
    main()

GUI代码:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file '.\Form.ui'
#
# Created: Fri Mar 20 15:17:05 2015
#      by: PyQt4 UI code generator 4.11.3
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_Form(object):
    def setupUi(self, Form):
        Form.setObjectName(_fromUtf8("Form"))
        Form.resize(282, 192)
        self.centralWidget = QtGui.QWidget(Form)
        self.centralWidget.setObjectName(_fromUtf8("centralWidget"))
        self.btn1 = QtGui.QPushButton(self.centralWidget)
        self.btn1.setGeometry(QtCore.QRect(20, 50, 91, 23))
        self.btn1.setObjectName(_fromUtf8("btn1"))
        self.btn2 = QtGui.QPushButton(self.centralWidget)
        self.btn2.setGeometry(QtCore.QRect(160, 50, 91, 23))
        self.btn2.setObjectName(_fromUtf8("btn2"))
        self.btn3 = QtGui.QPushButton(self.centralWidget)
        self.btn3.setGeometry(QtCore.QRect(110, 90, 75, 23))
        self.btn3.setObjectName(_fromUtf8("btn3"))
        self.label = QtGui.QLabel(self.centralWidget)
        self.label.setGeometry(QtCore.QRect(110, 20, 47, 13))
        self.label.setObjectName(_fromUtf8("label"))
        Form.setCentralWidget(self.centralWidget)
        self.menuBar = QtGui.QMenuBar(Form)
        self.menuBar.setGeometry(QtCore.QRect(0, 0, 282, 21))
        self.menuBar.setObjectName(_fromUtf8("menuBar"))
        Form.setMenuBar(self.menuBar)
        self.mainToolBar = QtGui.QToolBar(Form)
        self.mainToolBar.setObjectName(_fromUtf8("mainToolBar"))
        Form.addToolBar(QtCore.Qt.TopToolBarArea, self.mainToolBar)
        self.statusBar = QtGui.QStatusBar(Form)
        self.statusBar.setObjectName(_fromUtf8("statusBar"))
        Form.setStatusBar(self.statusBar)

        self.retranslateUi(Form)
        QtCore.QObject.connect(self.btn1, QtCore.SIGNAL(_fromUtf8("clicked()")), self.label.update)
        QtCore.QObject.connect(self.btn2, QtCore.SIGNAL(_fromUtf8("clicked()")), self.label.update)
        QtCore.QObject.connect(self.btn3, QtCore.SIGNAL(_fromUtf8("clicked()")), Form.close)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        Form.setWindowTitle(_translate("Form", "Form", None))
        self.btn1.setText(_translate("Form", "Start Recording", None))
        self.btn2.setText(_translate("Form", "Stop Recording", None))
        self.btn3.setText(_translate("Form", "Exit", None))
        self.label.setText(_translate("Form", "TextLabel", None))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    Form = QtGui.QMainWindow()
    ui = Ui_Form()
    ui.setupUi(Form)
    Form.show()
    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:1)

我认为你可能会误解你的程序执行情况。

PyQt(和所有GUI)应用程序都运行了一个事件循环。在PyQt的情况下,您使用app.exec_()开始此循环。直到GUI应用程序停止之前,该行下面的任何代码都不会运行。这是因为Python(故意)陷入exec_()方法中的循环中。

所以,您可能会问,如果程序卡在事件循环中,您的代码如何运行?事件循环(顾名思义)可以监听按钮点击,鼠标/键盘交互等事件。当您将鼠标移到按钮上时,事件循环甚至负责创建悬停效果。

当您单击第一个按钮时,事件循环将运行您的函数reader()。但是这个函数有一个无限循环。因此,应用程序的控制永远不会返回到PyQt事件循环。这意味着您无法点击其他按钮。如果将鼠标移动到应用程序中的任何按钮上,即使悬停效果也不会显示。 GUI应用程序依赖于控制被快速返回到事件循环以保持响应。

所以你永远不能点击第二个按钮来停止reader()中的循环,因为循环阻止所有其他代码运行。

解决方案是将reader()循环放在另一个线程中。但是,设置线程超出了本答案的范围。但是有很多资源在互联网上使用python线程和(Py)Qt QThreads(包括在stackoverflow上)。请注意,与GUI应用程序一起使用时,线程会带来一些风险。例如,您必须确保永远不会直接从辅助线程与GUI交互。

如果您遇到使用线程的问题,我会鼓励您发布另一个问题,显示您已经有多远,并说明您遇到的问题。我很乐意提供帮助!