将文本添加到生成的QListView窗口

时间:2018-06-08 11:14:46

标签: python python-3.x pyqt pyqt5 qlistview

教我自己python3想要使用print(消息)将数据发送到终端。这是相对直接的,我可以使用三行生成CAN数据的控制台列表(这里省略了代码的细节,只有裸代码):

import os #windows os only,
os.system('cls'),
print(myStr) (also not shown here in code, but it does work!)

想要把它全部搞定并开始扩展数据并显示它,在过去的一周里,我一直在学习qt5 designer和pyqt5以及pyuic来生成python的GUI。到目前为止一切都那么好,我可以让线程工作来读取CAN端口(对于那些不熟悉CAN总线的人来说很容易就是一个UART端口)通过控制台窗口仍然接收消息来确认这一点,并且GUI窗口显示出来。然后我读了一堆关于MVC并观看了教程,那是轮子开始脱落。我无法深入了解如何将数据加载到我的模型中以显示到GUI中的列表视图窗口。我想我可能已正确完成信号和插槽(如果不是这样的话,肯定有人会纠正我)但是我很难在正确的演示文稿中显示数据从 ?????? self.listView(str)

from PyQt5 import QtCore, QtGui, QtWidgets, QtSvg
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5.QtCore import pyqtSignal

import sys
import can
import threading
import time

class MainWindow(QMainWindow):

    app = None
    Form = None
    receiveUpdateSignal = pyqtSignal(str)

    def __init__(self,app):
        super().__init__()
        self.app = app
        self.initTool()  
        self.initEvent() 

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.listView = QtWidgets.QListView(Form)
        self.listView.setGeometry(QtCore.QRect(40, 40, 256, 192))
        self.listView.setObjectName("listView")

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    def retranslateUi(self, Form):
        _translate = QtCore.QCoreApplication.translate
        Form.setWindowTitle(_translate("Form", "Form"))

    def receiveCan(self):
        while True:
            try:
                message = self.bus.recv(0.2)
                if message is not None:                   
                    print(message)
                    #data = message.data 
                    self.receiveUpdateSignal.emit("messge in")               
            except Exception as e:
                if hasattr(e, 'message'):
                    print(e.message)
                else:
                    print(e)
                break
            time.sleep(0.005)

    def initTool(self):
        self. bus = can.interface.Bus(bustype='pcan', channel='PCAN_USBBUS1', bitrate=250000)
        return 

    def startReceive(self):
        receiveProcess = threading.Thread(target=self.receiveCan)
        receiveProcess.setDaemon(True)
        receiveProcess.start() 

    def initEvent(self):
        self.receiveUpdateSignal.connect(self.updateReceivedDataDisplay)

    def updateReceivedDataDisplay(self,str):
        if str != "":
            try:
                **??????self.listView (str)**
            except Exception as e:
                if hasattr(e, 'message'):
                    print(e.message)
                else:
                    print(e)
        return        

def main():

    app = QtWidgets.QApplication(sys.argv)
    Form = QtWidgets.QWidget()
    ui = MainWindow(app)
    ui.setupUi(Form)
    ui.startReceive()
    Form.show()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

1 个答案:

答案 0 :(得分:0)

首先不要使用str,它是Python中的保留字,它的使用被认为是糟糕的编程习惯。

另一方面,在QListView的情况下,这基于MVC模式,其中模型具有信息,视图显示它,控制器处理何时以及显示什么信息。在这种情况下,模型必须是一个继承自QAbstractListModel的类,最容易处理的类是QStandardItemModel,我们创建该类的对象并将其建立到QListView,在将信息添加到模型后,模型将在内部通知导致它更新的视图。

class MainWindow(QMainWindow):
    ...

    def setupUi(self, Form):
        Form.setObjectName("Form")
        Form.resize(400, 300)
        self.listView = QtWidgets.QListView(Form)
        self.listView.setGeometry(QtCore.QRect(40, 40, 256, 192))
        self.listView.setObjectName("listView")
        self.model = QtGui.QStandardItemModel()   # <----
        self.listView.setModel(self.model)        # <----

        self.retranslateUi(Form)
        QtCore.QMetaObject.connectSlotsByName(Form)

    ...

    def updateReceivedDataDisplay(self, text):
        if text:
            it = QtGui.QStandardItem(text)
            self.model.appendRow(it)