无法停止导入数据

时间:2016-10-25 22:46:27

标签: python qt import pyqt4 qt-designer

我使用python编写了一个数据采集代码,现在我尝试使用Qt Designer将我的代码与GUI应用程序连接起来。我的问题是当我通过单击主窗口上的startButton导入我的数据采集代码(sensor.py)时,程序开始收集数据,但是我无法通过单击stopButton来阻止它,甚至我也无法按任何其他按钮,而我必须关闭我的主项目才能停止收集数据。

这是我的主要项目代码:

 #include <stdio.h>

long int p(long int b, long int e)
{
  long int i;
  long int prod;
  prod = b * e;

  if(prod <= 0)
    return 0;
  prod = 1;
  for(i=b ; i<=e ; ++i)
    prod*=i;
  return prod;
}

int main(void)
{
  long int b, e;

  scanf("%li %li", &b, &e);

  printf("The product from range %li to %li is %i \n", b, e, p(b,e));

  return 0;
}

sensor.py代码:

from PyQt4 import QtCore, QtGui
import sys

from mainwindow import Ui_MainWindow
from gpiodialog import Ui_GPIODialog
from savedialog import Ui_SaveDialog


class dataAcquisition(QtGui.QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(dataAcquisition, self).__init__(parent)
        self.setupUi(self)


###################The problem is under here###################
        self.startButton.clicked.connect(self.startButton_clicked)
    def startButton_clicked(self):
        import sensor

        self.stopButton.clicked.connect(self.stopButton_clicked)
    def stopButton_clicked(self):
###############################################################



        self.gpioButton.clicked.connect(self.gpioButton_clicked)
        self.popGPIO = gpioDialog()
    def gpioButton_clicked(self):
        self.popGPIO.show()

        self.saveButton.clicked.connect(self.saveButton_clicked)
        self.popSave = saveDialog()
    def saveButton_clicked(self):
        self.popSave.show()


class gpioDialog(QtGui.QDialog, Ui_GPIODialog):
    def __init__(self, parent=None):
        super(gpioDialog, self).__init__(parent)

        flags = QtCore.Qt.Drawer | QtCore.Qt.WindowStaysOnTopHint
        self.setWindowFlags(flags)

        self.setupUi(self)
        self.gpioOKButton.clicked.connect(self.acceptOKButtonClicked)

    def acceptOKButtonClicked(self):
        self.close()        


class saveDialog(QtGui.QDialog, Ui_SaveDialog):
    def __init__(self, parent=None):
        super(saveDialog, self).__init__(parent)

        flags = QtCore.Qt.Drawer | QtCore.Qt.WindowStaysOnTopHint
        self.setWindowFlags(flags)

        self.setupUi(self)
        self.saveOKButton.clicked.connect(self.acceptOKButtonClicked)

    def acceptOKButtonClicked(self):
        self.close()        


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    MainWindow = dataAcquisition()
    MainWindow.show()
    sys.exit(app.exec_())

我尝试使用线程并编辑我的代码,如下所示,现在我正在打印数据,但我的GUI应用程序没有弹出!有谁知道为什么?

如果有人可以提供帮助,我将不胜感激。

新代码:

#!/usr/local/bin/python

## Reading data from a photocell sensor

import RPi.GPIO as GPIO
import time

# Tell the GPIO library to use Broadcom GPIO references
GPIO.setmode(GPIO.BOARD)

#define the pin that goes to the circuit
Pin = 7

def RCtime (Pin):
  measurement = 0
  #Output on the pin for # Discharge capacitor
  GPIO.setup(Pin, GPIO.OUT)
  GPIO.output(Pin, GPIO.LOW)
  time.sleep(0.0001)

  GPIO.setup(Pin, GPIO.IN)
  # Count loops until voltage across capacitor reads high on GPIO

  while (GPIO.input(Pin) == GPIO.LOW):
    measurement += 1
  return measurement

# Main program loop
i = 1
while True:
    file1 = open("Data%i.txt" %i ,"w")
    i += 1 
    c = 1
    while c <= 50:
        print RCtime (Pin)*1.000
        c += 1
        file1.write(str(RCtime (Pin)))
        file1.write("\n")

    else:
      file1.close()

1 个答案:

答案 0 :(得分:1)

###################The problem is under here###################
        self.startButton.clicked.connect(self.startButton_clicked)
    def startButton_clicked(self):
        import sensor

        self.stopButton.clicked.connect(self.stopButton_clicked)
    def stopButton_clicked(self):
###############################################################
你是对的。问题出在这里。

您将开始按钮回调startButton_clicked定义为

def startButton_clicked(self):
    # Data acquisition
    import sensor
    # Connect stop callback
    self.stopButton.clicked.connect(self.stopButton_clicked)

这里的问题是数据采集脚本最终会出现无限循环,因此它永远不会返回,GUI永远无法获得控制权。

您应该在线程中使用传感器脚本,以便在运行时不会阻止GUI。

BTW,请注意您可以在__init__()时间建立所有回拨连接。如果您不希望在没有任务运行时停止按钮处于活动状态,请使用set_enabled(False)使其处于非活动状态。

这是线程的样子:

来自线程导入线程 将RPi.GPIO导入为GPIO 进口时间

class Sensor(Thread):

    def __init__(self, stop_request):
        threading.Thread.__init__(self)
        self.stop_request = stop_request

    def run(self):
        # The run method is called internally when you call Sensor.start()
        # and is executed in a separate thread

        # Tell the GPIO library to use Broadcom GPIO references
        GPIO.setmode(GPIO.BOARD)

        #define the pin that goes to the circuit
        Pin = 7

        def RCtime (Pin):
            measurement = 0
            #Output on the pin for # Discharge capacitor
            GPIO.setup(Pin, GPIO.OUT)
            GPIO.output(Pin, GPIO.LOW)
            time.sleep(0.0001)

            GPIO.setup(Pin, GPIO.IN)
            # Count loops until voltage across capacitor reads high on GPIO

            while (GPIO.input(Pin) == GPIO.LOW):
                measurement += 1
            return measurement

        # Main program loop
        i = 1
        # Run until stop request event is set
        while not self.stop_request.is_set():
            # Note you can use this syntax for file handling
            with open("Data%i.txt" %i ,"w") as file1:
                # And you can use range to loop 50 times,
                # no need to use explicit loop variable like in C
                for _ in range(50):
                    print RCtime (Pin)*1.000
                    file1.write(str(RCtime (Pin)))
                    file1.write("\n")
            i += 1

        # Clear stop request event
        self.stop_request.clear()

Sensor对象插入主代码中,如下所示:

from sensor import Sensor
from threading import Event

class dataAcquisition(QtGui.QMainWindow, Ui_MainWindow):

    def __init__(self, parent=None):
        super(dataAcquisition, self).__init__(parent)
        self.setupUi(self)

        # Initialize stop request event
        self.stop_request = Event()

    def startButton_clicked(self):

        # Initialize thead, passing the event
        self.sensor = Sensor(self.stop_request)

        # Start thread
        self.sensor.start()

    def stopButton_clicked(self):
        # Set stop_request event to ask the thread to stop
        self.stop_request.set()

我让你弄清楚GUI部分。这是另一个故事。 (在用户按下停止按钮和线程实际停止的那一刻之间可能会有一点时间,所以在理想的世界中,您可能希望在重新启用开始按钮之前等待线程实际完成。搜索Thread.join()。)

此代码完全未经测试。我不是Threading专家。我只想读出docs

如果它不能立即起作用,它应该是最好的暗示。