【问题标题】:PyQt5 GUI with Raspberry Pi Hardware带有 Raspberry Pi 硬件的 PyQt5 GUI
【发布时间】:2021-03-31 02:33:43
【问题描述】:

我正在编写使用 basler 相机进行对象测试的代码,并为其创建了基于 PyQt5 的 GUI。我的 GUI 工作正常,但现在我必须为其集成外部硬件。为了。前任。我必须从 GUI 中选择和对象,然后我将在对焦灯打开后按下外部开关捕获图像并将其与给定的宽度条件进行比较,并在 GUI 上显示输出,即选择了哪个作业并且它是否匹配。

当我按下开关时,我的 GUI 冻结并且我没有在 GUI 屏幕上得到结果。 如果我做错了什么,请帮助我

import cv2
import numpy as np
import time
from pypylon import pylon
import sys
from PyQt5.QtWidgets import QApplication, QMainWindow, QLabel, QComboBox
from RPi import GPIO as GPIO
GPIO.setwarnings(False)

class Receipe(QMainWindow):
    
    def __init__(self):
        super().__init__()
        combo = QComboBox(self)
        combo.addItem("A")
        combo.addItem("B")
        combo.addItem("C")
        combo.move(50, 50)
        self.qlabel = QLabel(self)
        self.qlabel.move(50, 16)
        combo.activated[str].connect(self.onChanged)
        self.status = QLabel(self)
        self.status.move(50, 86)
        self.setGeometry(50, 50, 320, 200)
        self.setWindowTitle("Receipe Selection")
        self.show()
        
        
        
        self.light_switch = 16
        self.relay_light = 8
        GPIO.setmode(GPIO.BOARD)
        GPIO.setup(self.light_switch, GPIO.IN)
        GPIO.setup(self.relay_light, GPIO.OUT)
        GPIO.output(self.relay_light, False)

    def onChanged(self, text):
        self.qlabel.setText("Type"+" "+text+" "+"Job Is Selected")
        self.qlabel.adjustSize()
        
        #mention coondition here
        img = Camera().frame
        print ("Capture Frame")
        while True:
            if GPIO.input(self.light_switch) == 0:
                print ("Switch Pressed")
                time.sleep(1)
                GPIO.output(self.relay_light,True)
                time.sleep(1)
                process = ImgProcess()
                print ("Process Image")
                GPIO.output(self.relay_light, False)
                result = process.process(text,img)
                print(result)              
                if result == True:
                    print("in result")
                    self.status.setText("Ok")
                else:
                    self.status.setText("Not Ok")


class Camera:
    def __init__(self):
        self.serial_no = "23252513"
        self.ExposureTime = 4000
        self.device_id = None
        devices = [i.GetSerialNumber() for i in pylon.TlFactory.GetInstance().EnumerateDevices()]
        if self.serial_no in devices:
                self.device_id = "23252513"
        else:
            print('Camera not found')

        info = pylon.DeviceInfo()
        info.SetSerialNumber(self.serial_no)
        self.camera = pylon.InstantCamera(pylon.TlFactory.GetInstance().CreateFirstDevice(info))
        # self.camera = pylon.InstantCamera(pylon.TlFactory.CreateDevice(self.device_id))
        self.camera.Open()
        self.camera.ExposureAuto.SetValue('Off')
        self.camera.ExposureTimeRaw.SetValue(self.ExposureTime)
        self.camera.StartGrabbing(pylon.GrabStrategy_LatestImageOnly)


    @property
    def frame(self):
        if self.device_id is not None:
            converter = pylon.ImageFormatConverter()
            converter.OutputPixelFormat = pylon.PixelType_BGR8packed
            converter.OutputBitAlignment = pylon.OutputBitAlignment_MsbAligned

            while self.camera.IsGrabbing():
                try:
                    try:
                        grabResult = self.camera.RetrieveResult(5000, pylon.TimeoutHandling_ThrowException)
                    except pylon.TimeoutHandling_ThrowException as e:
                        print(e)
                    except Exception as e:
                        print(e)

                    if grabResult.GrabSucceeded():
                        frame = converter.Convert(grabResult).GetArray()
                        return frame
                    else:
                        print('Camera not found')
                    grabResult.Release()
                except Exception as e:
                    print(e)
            else:
                print('Camera not found')
            self.camera.StopGrabbing()

    def close(self):
        self.camera.Close()

class ImgProcess:
    def __init__(self):
        self.data = None
        self.relay_ok = 10
        self.relay_faulty = 12
        GPIO.setup(self.relay_ok, GPIO.OUT)
        GPIO.setup(self.relay_faulty, GPIO.OUT)
        GPIO.output(self.relay_ok, False)
        GPIO.output(self.relay_faulty, False)
        
    def process(self,txt,img):
        self.data = txt
        result = ""
        status = True
        oimg = img
        gimg = cv2.cvtColor(oimg, cv2.COLOR_BGR2GRAY)
        bw_img = cv2.inRange(gimg, 0, 130)
        kernel = np.ones((2, 2), np.uint8)
        erode_img = cv2.dilate(bw_img, kernel=kernel, iterations=1)
        cntr, hierarchy = cv2.findContours(erode_img, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
        cntr = sorted(cntr, key=cv2.contourArea)
        job_cntr = cntr[-1]
        x, y, w, h = cv2.boundingRect(job_cntr)
        cv2.rectangle(oimg, (x, y), (x + w, y + h), (0, 0, 255), 2)
        # print(x, y, w, h)

        if w < 700:
            result = "A"
            print("TYPE-A Job Is Detected")
        elif (w > 800) and (w < 900):
            result = "B"
            print("TYPE-B Job Is Detected")
        elif (w > 900) and (w < 1000):
            result = "C"
            print("TYPE-C Job Is Detected")
        else:
            print("INVALID JOB")

        if result == self.data:
            GPIO.output(self.relay_ok,True)
            time.sleep(1)
            GPIO.output(self.relay_ok,False)
            print("Ok")
            
        else:
            GPIO.output(self.relay_faulty,True)
            time.sleep(1)
            GPIO.output(self.relay_faulty,False)
            print("Faulty")
            status = False
        
        return status


if __name__ == '__main__':
    app = QApplication(sys.argv)
    recp = Receipe()
    sys.exit(app.exec_())

【问题讨论】:

  • 有很多代码要阅读。您是否有机会将其简化为重现该问题的最小示例?
  • 我建议使用 PDB 或类似的东西来遍历您的代码以检查它冻结的位置。
  • @Ludo21South 你能详细说明什么是 PDB 吗?
  • @101 我的 GUI 代码卡在 onchanged 函数中
  • 原因正是 Ludo21South 所指出的:UI 框架应该从不在其主线程中具有阻塞函数(例如time.sleep)或阻塞循环,否则会导致ui 无响应且无法自行更新,这是因为它们阻止了事件队列的处理。为了进行并行处理和访问 UI,QThreads 必须与自定义信号一起使用(因为 NO 允许从外部线程直接访问 UI 元素)

标签: python user-interface pyqt5 gpio raspberry-pi4


【解决方案1】:

你不能在 def onChanged(self, text) 中这样做

if GPIO.input(self.light_switch) == 0:

如果您这样做,您的应用程序将会死机。 如果您想使用 GPIO 引脚,请使用 gpiozero 库,在您的情况下,您将不得不使用对象 Button

看看这个: https://gpiozero.readthedocs.io/en/stable/recipes.html#button

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-21
    • 2022-08-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-20
    • 1970-01-01
    相关资源
    最近更新 更多