Добавление текста в сгенерированное окно QListView - PullRequest
0 голосов
/ 08 июня 2018

Во время обучения себя 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.Пока все хорошо, и я могу заставить поток работать, чтобы читать порт CAN (который мог бы быть просто портом UART для тех, кто не знаком с шиной CAN), подтвердил это с окном консоли, все еще получающим сообщения, и окно GUI появляется.Затем я прочитал кучу о MVC и посмотрел учебные пособия, и вот тут колеса начали отваливаться.Я не могу понять, как загрузить данные в мою модель для отображения в окне просмотра списка в графическом интерфейсе.Я думаю, что у меня мог бы быть правильно сделан сигнал и слот (уверен, что кто-то исправит меня, если это не так), но я изо всех сил пытаюсь получить данные в правильном представлении, которые будут отображены из строки ??????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 голосов
/ 08 июня 2018

Прежде всего, не используйте 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)  
...