简体   繁体   English

QTableWidget:插入行会使应用程序python崩溃

[英]QTableWidget: Insert row crashes the application python

I have created a table and I want the row should be created based on click on one button. 我已经创建了一个表,我希望基于单击一个按钮来创建行。 I created a table and I didn't assign rowcount. 我创建了一个表,但没有分配行数。 When I run program, it shows table without any row (shows header label etc). 当我运行程序时,它显示没有任何行的表(显示标题标签等)。 So far everything is fine. 到目前为止,一切都很好。 I put a button to add a row and wrote following code: 我放了一个按钮以添加一行,并编写了以下代码:

self.tableWidget.InsertRow(self.tableWidget.rowCount()+1)

The application simply exits. 该应用程序直接退出。

If I try: 如果我尝试:

self.tableWidget.setRowCount(count+1)

it adds row. 它添加行。 Suppose I entered some data in rows and again call 假设我在行中输入了一些数据,然后再次调用

self.tableWidget.setRowCount(count+1)

it deletes data of one row. 删除一行数据。

My question is: 我的问题是:

Can we use InsertRow without setting setRowCount? 我们可以在不设置setRowCount的情况下使用InsertRow吗?

When I call setRowCount multiple time, why does it delete data filled in rows (using UI)? 当我多次调用setRowCount时,为什么它会删除填充行的数据(使用UI)?

I could implement something simpler to show exactly just what you are asking for, but I just implemented something similar to what you need, I needed to do what you need to get data from a table and fill out my QLineChart. 我可以实现一些更简单的操作,以准确地显示您的要求,但是我实现了与您需要的操作类似的操作,我需要做您需要的操作,以便从表中获取数据并填写我的QLineChart。

In summary you have to override all the required methods a QAbstractItemModel requires according to your needs. 总之,您必须根据需要重写QAbstractItemModel所需的所有必需方法。

Have this small example that I add a line to the and of my table when clicking in a button: 有一个小的示例,当我单击按钮时,我在表的和中添加了一行:

import random

from PyQt5.QtCore import QAbstractItemModel
from PyQt5.QtCore import QModelIndex
from PyQt5.QtCore import QRect
from PyQt5.QtCore import QVariant
from PyQt5.QtCore import Qt
from PyQt5.QtCore import pyqtSignal
from PyQt5.QtGui import QColor


class ItemModelLineChart(QAbstractItemModel):

    signal_update_models = pyqtSignal()

    def __init__(self):
        super(ItemModelLineChart, self).__init__()
        self.m_column_count = 2
        self.m_row_count = 0
        self.m_mapping = {}
        self.m_data = []
        # self.fill_with_random_data()

    def fill_with_random_data(self):
        print(self.m_row_count)
        for r in range(self.m_row_count):
            data_vec = [None] * self.m_column_count
            for c in range(len(data_vec)):
                if (c%2)==0:
                    data_vec[c] = r*50+random.randint(0,100)%20
                else:
                    data_vec[c] = random.randint(0, 100) % 20
            self.m_data.append(data_vec)

    def rowCount(self, parent=None, *args, **kwargs):
        return len(self.m_data)

    def columnCount(self, parent=None, *args, **kwargs):
        return self.m_column_count

    def headerData(self, section, orientation, role=None):
        if role == Qt.DisplayRole:
            return QVariant()
        if orientation == Qt.Horizontal:
            if section%2==0:
                return "x"
            else:
                return "y"
        else:
            return "{}".format(section+1)

    def data(self, index, role=None):
        if role == Qt.DisplayRole:
            return self.m_data[index.row()][index.column()]
        elif role == Qt.EditRole:
            return self.m_data[index.row()][index.column()]
        elif role == Qt.BackgroundRole:
            for color, rect in self.m_mapping.items():
                if rect.contains(index.column(), index.row()):
                    return QColor(color)
        return QVariant()

    def setData(self, index, value, role=None):
        if index.isValid() and role == Qt.EditRole:
            self.m_data[index.row()][index.column()] = int(value)
            self.dataChanged.emit(index,index)
            self.signal_update_models.emit()
            return True
        return False

    def get_data(self, index):
        return self.m_data[index.row()][index.column()]

    def add_mapping(self, color, area):
        self.color = color
        self.area = area
        self.m_mapping[color] = area

    def flags(self, index):
        return Qt.ItemIsEditable | Qt.ItemIsEnabled
        # if (index.column() == 0):
        #     return Qt.ItemIsEditable | Qt.ItemIsEnabled
        # else:
        #     return Qt.ItemIsEnabled

    def index(self, row, column, parent=None, *args, **kwargs):
        if self.hasIndex(row,column,parent):
            return self.createIndex(row,column,self.m_data[row])
        return QModelIndex()

    def parent(self, index=None):
        return QModelIndex()

    def insertRows(self):
        self.beginInsertRows(QModelIndex(), self.m_row_count, self.m_row_count)

        self.m_data.append([0,0])
        self.m_row_count += 1
        self.add_mapping(self.color, QRect(0, 0, 2, self.rowCount()))
        self.endInsertRows()
        return True

    def removeRows(self):
        self.beginRemoveRows(QModelIndex(), self.m_row_count, self.m_row_count)
        self.m_data.pop()
        self.m_row_count -= 1
        self.endRemoveRows()

        return True

    def add_row(self):
        self.insertRows()

    def remove_row(self):
        if self.m_row_count>0:
            self.m_row_count -= 1
            self.removeRows()

and in the widget or whatever you have your buttons just connect your button clicking to the insert and remove line methods from your item model above. 在窗口小部件或任何您拥有按钮的地方,只需将您的按钮连接到上面的项目模型中的插入和删除行方法即可。

#...
    def create_connections(self):
        self.btn_add_line.clicked.connect(self.table.model().insertRows)
        self.btn_remove_line.clicked.connect(self.table.model().remove_row)
#...

Now you just gotta set the model from your tableview to the model you overwrote. 现在,您只需将模型从表视图设置为重写的模型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM