for testing purposes a have function that asks for input and displays it in a QListView
display data.
this works fine with one dim.data
I want to extend the script to display two-dimensional data
the incoming data should be inserted in the first row till column 3, and proceeds on the next rows (same operation) so the model contains the data in this form
input_values = [[1,2],
[1,2]]....
so far I implemented that the input_data is added into the first row, but the script stops running before it starts adding the data into the second row. I just get this info
Process finished with exit code -1073740791 (0xC0000409)
What is cousing this behavior and how to fix that ?
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()
full code
#!/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_())
The issue you are getting is an IndexError since the data is not being added uniformly (whole row at a time), it is being added one column, or cell, at a time. As a result, when starting the next row with the 3rd input, there is no data for the 2nd column in that row yet. You don't necessarily have to change the way you are inserting data, just catch the error and supply an empty string or None value.
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
Additionally, make sure you are accessing the correct index of input_data
in thread_data_add()
, which would be the last index [-1] since you are appending data.
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()
User contributions licensed under CC BY-SA 3.0