将动态数据添加到细分的QAbstractTableModel中

问题描述 投票:5回答:1

出于测试目的,具有一个要求输入并将其显示在QListView中的功能display data。这与一个dim.data正常工作我想扩展脚本以显示二维数据

输入的数据应插入到第一行,直到第3列,然后在下一行继续进行(相同的操作,因此模型包含此形式的数据

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

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

Process finished with exit code -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_())






python pyqt pyqt5
1个回答
2
投票

您遇到的问题是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

此外,请确保您正在访问input_data中的thread_data_add()的正确索引,这是自添加数据以来的最后一个索引[-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()
© www.soinside.com 2019 - 2024. All rights reserved.