python - 将动态数据添加到子类 QAbstractTableModel

标签 python pyqt pyqt5

出于测试目的,有一个函数要求输入并将其显示在QListViewdisplay data 。 这对于一个 dim.data 来说效果很好
我想扩展脚本来显示二维数据

传入的数据应插入到第一行直到第 3 列,并继续处理下一行(相同的操作),以便模型包含这种形式的数据

 input_values = [[1,2],
                 [1,2]]....

到目前为止,我实现了将 input_data 添加到第一行,但脚本在开始将数据添加到第二行之前停止运行。我刚刚得到这个信息

进程已完成,退出代码为 -1073740791 (0xC0000409)

是什么导致了这种行为以及如何解决这个问题?

    def thread_data_add(self, data):
        if len(self.model.input_data[0]) <= 1:
            self.model.input_data[0].append(data)
            self.model.layoutChanged.emit()

        elif len(self.model.input_data[0]) > 1:
            self.model.input_data.append([])
            self.model.input_data[1].append(data) #crashes here !!! need crash report
            self.model.layoutChanged.emit()


完整代码

#!/usr/bin/env python

"""


"""


import threading
import sys
import logging

from PyQt5 import QtWidgets as qtw
from PyQt5 import QtCore as qtc
from PyQt5 import QtGui as qtg


class ViewModel(qtc.QAbstractTableModel):


    def __init__(self, input_data=None):
        super().__init__()
        self.input_data = input_data or [[]]
        #


    def data(self, index, role): # parameter index, role are needed !
        """

        :param index: Instance of QModelIndex Class  / set automatically
        Model indexes refer to items in models,
         contain all the information required to specify their locations in those models

        :param role: what type should be returned
        :return: data as a string
        """
        if role == qtc.Qt.DisplayRole:
            row = index.row()
            column = index.column()
            text = self.input_data[row][column] 
            return text



    def rowCount(self, index):
        return len(self.input_data)

    def columnCount(self, index):
        return len(self.input_data[0])


    def getData(self):
        print(self.input_data)
        # todo how to show list data





class MainWindow(qtw.QWidget):

    core_signal = qtc.pyqtSignal(str)


    def __init__(self):
        super().__init__()

        # View
        table_view = qtw.QTableView()
        self.model = ViewModel()
        table_view.setModel(self.model)

        # widgets
        self.start_thread_button = qtw.QPushButton("start Thread")
        self.test_button = qtw.QPushButton("display data")

        # layout
        qvboxlayout = qtw.QVBoxLayout()
        qvboxlayout.addWidget(table_view)

        qvboxlayout.addWidget(self.start_thread_button)
        qvboxlayout.addWidget(self.test_button)
        self.setLayout(qvboxlayout)
        self.show()


        # self.logger = self.default_logger()


        # function

        self.start_thread_button.clicked.connect(self.start)
        self.test_button.clicked.connect(self.model.getData)


    def lambda_thread_data_add(self, data):
        if len(self.model.input_data[0]) <= 1:
            self.model.input_data[0].append(data)
            self.model.layoutChanged.emit()
            # self.model.input_data.append([])
        elif len(self.model.input_data[0]) > 1:
            self.model.input_data.append([])
            self.model.input_data[1].append(data) #crashes here !!! need crash report
            self.model.layoutChanged.emit()



    def thread_data_add(self, data):
        if len(self.model.input_data[0]) <= 1:
            self.model.input_data[0].append(data)
            self.model.layoutChanged.emit()
            # self.model.input_data.append([])
        elif len(self.model.input_data[0]) > 1:
            self.model.input_data.append([])
            self.model.input_data[1].append(data) #crashes here !!! need crash report
            self.model.layoutChanged.emit()



    def start(self):
        # starts thread
        # Setting thread.daemon = True will allow the main program to exit before thread is killed.
        threading.Thread(target=self._execute, daemon=True).start()
        self.core_signal.connect(self.thread_data_add)


    def _execute(self):
        while True:
            user_input = input("type in: ")
            self.core_signal.emit(user_input) # transmit data


    def default_logger(self,level=logging.DEBUG, save_path='beispiel.log'):
    # create logger
        custom_logger = logging.getLogger(__name__)
        custom_logger.setLevel(level)

        # was reingegeben werden soll
        formatter = logging.Formatter('%(asctime)s;%(message)s;%(filename)s;%(lineno)d', "%Y-%m-%d %H:%M:%S")
        file_handler = logging.FileHandler(save_path)
        file_handler.setFormatter(formatter)
        custom_logger.addHandler(file_handler)

        stream_handler = logging.StreamHandler()
        custom_logger.addHandler(stream_handler)

        return custom_logger

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






最佳答案

您遇到的问题是 IndexError,因为数据没有统一添加(一次整行),而是一次添加一列或单元格。因此,当使用第三个输入开始下一行时,该行中的第二列还没有数据。您不必更改插入数据的方式,只需捕获错误并提供空字符串或 None 值即可。

def data(self, index, role):
    if role == qtc.Qt.DisplayRole:
        try:
            text = self.input_data[index.row()][index.column()]
        except IndexError:
            text = None
        return text

此外,请确保您在 thread_data_add() 中访问 input_data 的正确索引,这将是您追加数据后的最后一个索引 [-1]。

def thread_data_add(self, data):
    if len(self.model.input_data[-1]) < 2:
        self.model.input_data[-1].append(data)
    else:
        self.model.input_data.append([data])
    self.model.layoutChanged.emit()

关于python - 将动态数据添加到子类 QAbstractTableModel,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61320830/

相关文章:

python - 在 Python 中将数字格式化为字符串

python - 如何在 PyQt 中创建自定义形状 QPushBtn

python - 如何在 PyQt 中绘制自定义椭圆形?

python - 使用 PyQT 伪透明

python - 为什么我的 QFileSystemModel QModelIndex 无法获取子节点信息?

python - PyQt5 和 Anaconda : ModuleNotFoundError: No module named 'PyQt5'

python - 如何在if语句中退出python脚本

python - 将 kivy 应用程序打包成一个 exe

qt - 如何为 PyQt5 构建 Qt WebEngine?

python - 将 Dash 应用部署到 Heroku : error code=H10, H13