【问题标题】:PyQt5.QtSerialPort don't call connected function when called from other classPyQt5.QtSerialPort 从其他类调用时不调用连接函数
【发布时间】:2017-09-01 22:31:51
【问题描述】:

关于从其他类调用 PyQt5.QtSerialPort 我有一个奇怪的(对我来说)问题:

这是我想从其他对话框或类调用的串行代码类实现:

# -*- coding: utf-8 -*-
import sys
from PyQt5.QtWidgets import QApplication
from PyQt5.QtCore import QObject, QIODevice, pyqtSignal
from PyQt5.QtSerialPort import QSerialPort

class Com_port(QObject):
    ser = None
    packet_received = pyqtSignal(int)
    packet = [0,1,2,3,4,5,6,7,8,9,10,11,12]

    def __init__(self, *args, **kwds):
        super(Com_port, self).__init__()
        #self.buffer = kwds.pop('buffer')
        self.ser = QSerialPort(kwds.pop('port'))
        #self.ser = QSerialPort("COM5")
        self.ser.open(QIODevice.ReadWrite)
        self.ser.setBaudRate(kwds.pop('baudrate'))
        #self.ser.setBaudRate(115200)
        self.ser.readyRead.connect(self.on_serial_read)
        self.packet_received.connect(self.rcvData_signal)

        self.b1_bmsovi=b'\x0d\x0e\x0f\x10\x11\x12'
        self.brojac=0
        self.bms_number=0
        self.b1_bmsovi=b'\x0d\x0e\x0f\x10\x11\x12'
        self.brojac=0
        self.bms_number=0
        print ("Ipak sam prozvan")

    def rcvData_signal(self,bms):
        print(bms)

    def check_packet(self):
        rezultat = 0
        if self.packet[0]==170 and self.packet[1]==200 and self.packet[3]==1 and self.packet[12]==85 and (self.packet[2] in self.b1_bmsovi):
            self.bms_number = self.packet[2]
            rezultat = 1
        return rezultat

    def process_bytes(self, bs):
        """
        """
        for b in bs:
            if b == 170:
                self.brojac=0
            if self.brojac < 13:
                print (b)
                self.packet[self.brojac] = b
                self.brojac += 1
            if self.brojac==12 and self.check_packet()==1:
                self.packet_received.emit(self.bms_number)

    def on_serial_read(self):
        """
            Called when the application gets data from the connected device.
        """
        self.process_bytes(bytes(self.ser.readAll()))
# end of class Com_port

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ComPortApp = Com_port(port="COM5",baudrate=115200)
    sys.exit(app.exec_())
    """
    Korisni linkovi
    https://programtalk.com/vs2/python/8876/mu/mu/interface.py/
    """

当我单独执行此代码时,我从打印 bms 编号的 rcvData_signal(self,bms) 函数得到结果。

所以我想使用这个类作为来自 com 端口的通用串行数据源。 我写这段代码只是为了测试 Com_port 类:

import sys
from PyQt5.QtCore import Qt
from PyQt5.QtWidgets import *
from bms_single_ui import Ui_bms_single
from com_port_thread import Com_port

class bms_single(QMainWindow):
    def __init__(self, parent=None):
        QWidget.__init__(self, parent)

        ser=Com_port(port="COM5",baudrate=115200) # Com_port instance
        ComPortApp.packet_received.connect(self.rcvData_signal) #event redir

        self.ui = Ui_bms_single()
        self.ui.setupUi(self)
        self.setWindowTitle("BMS SINGLE PREVIEW")
        self.setWindowFlags(Qt.FramelessWindowHint)
        #self.setWindowFlags(Qt.Window | Qt.WindowTitleHint | Qt.CustomizeWindowHint )
        self.setFixedSize(800,480)
        self.move(0, 0)

    def rcvData_signal(self,bms):   # No calling to this :(
        print(bms)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    #ComPortApp = Com_port(port="COM5",baudrate=115200)
    sys.exit(app.exec_())

在这种情况下,我无法从 Com_port 实例中获取任何数据 :(

但是当我取消注释代码底部的这一行 #ComPortApp = Com_port(port="COM5",baudrate=115200) (并在 bms_singe 类中注释所有关于 com 端口的行)时,我从 Com_port 实例中获取了所有数据.

从 bms_single 类调用 Com_port 类有什么问题?

【问题讨论】:

  • ComPortApp.packet_received.connect(self.rcvData_signal) #event redir 在第一次列出时不正确它应该是 ser.packet_received.connect(self.rcvData_signal) #event redir 但它仍然不工作

标签: python pyqt pyqt5


【解决方案1】:

根据documentation

'__main__' 是顶级代码执行的范围的名称。 当从标准输入、脚本或交互式提示中读取时,模块的 __name__ 设置为等于 '__main__'

[..]

从上面我们得出结论,只有一个if __name__ ==" __main__ " 被执行:“。如果其他文件中存在相同的表达式,它们将被省略。所以你不应该使用变量ComPortApp,因为它不存在,正确的做法是使用变量ser,在你的情况下它改变了:

ComPortApp.packet_received.connect(self.rcvData_signal)

到:

ser.packet_received.connect(self.rcvData_signal)

另一个问题是对象ser正在被垃圾收集器清除,有2个选项:

  1. 为其创建变量ser 类成员更改为在bms_single 类中的self.ser 中。

self.ser=Com_port(port="COM5",baudrate=115200) # Com_port instance
self.ser.packet_received.connect(self.rcvData_signal) #event redir
  1. 将父属性传递给 Com_port 类,您必须更改以下内容:

ser= Com_port(port="COM5",baudrate=115200, parent=self)

class Com_port(QObject):
    [...]

    def __init__(self, *args, **kwds):
        super(Com_port, self).__init__(kwds.pop('parent'))

我还建议将QWidget.__init__(self, parent) 更改为QMainWindow.__init__(self, parent)

最后不要忘记在 main 中创建并显示 bms_single 的实例。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = bms_single()
    w.show()
    sys.exit(app.exec_())

【讨论】:

    猜你喜欢
    • 2013-07-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多