【问题标题】:Adding text to a QListView window generated将文本添加到生成的 QListView 窗口
【发布时间】:2018-06-08 11:14:45
【问题描述】:

在自学 python3 时想要使用 print(message) 向终端发送数据。这是相对简单的,我可以使用三行生成 CAN 数据的控制台列表(此处省略代码的详细信息,只有最小的代码):

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

想要美化它并开始扩展数据并显示它,上周一直在学习 qt5 设计器和 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()

【问题讨论】:

  • 您必须实现抽象类QAbstractItemModel,然后使用listview.setModel(),您可以将其设置为您的列表视图。最好的办法是阅读课程的详细说明。这是QAbstactItemModeldoc.qt.io/qt-5/qabstractitemmodel.html的链接
  • 感谢您的链接。在周末阅读它并为我提供了一个很好的资源,以及@eyllanesc 答案能够阅读有关 QStandardITemModel 并在我的脑海中建立联系术语是什么以及它如何在代码中组合在一起并概念化更多关于如何它在平台后台运行。

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


【解决方案1】:

首先不要使用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)  

【讨论】:

  • 感谢 eyllanesc。我添加了这四行,它就起作用了。随着@Blinxen 的评论能够看到在这种情况下StandartItemModel 如何使用appendRow() 更简单一些,而不必担心beginInsertRow()。顺便说一句,永远不会故意为变量使用保留字(来自 C 嵌入式世界)!随着我对这门语言越来越熟悉,我会避免此类错误。
猜你喜欢
  • 1970-01-01
  • 2018-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多