добавление данных Dynami c в субклассированную QAbstractTableModel - PullRequest
5 голосов
/ 20 апреля 2020

для целей тестирования есть функция, которая запрашивает ввод и отображает его в QListView отображаемых данных . это прекрасно работает с одним 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_())






1 Ответ

2 голосов
/ 24 апреля 2020

Проблема, которую вы получаете, - это ошибка IndexError, поскольку данные не добавляются равномерно (целая строка за раз), они добавляются по одному столбцу или ячейке за раз. В результате при запуске следующей строки с 3-го ввода данных для 2-го столбца в этой строке еще нет. Вам не обязательно менять способ вставки данных, просто перехватите ошибку и укажите пустую строку или значение 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()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...