【问题标题】:Insert and remove row in pyqts QTableView using the QAbstractTableModel使用 QAbstractTableModel 在 pyqts QTableView 中插入和删除行
【发布时间】:2021-03-26 23:26:06
【问题描述】:

如何使用 QAbstractTableModel 在 QTableView 中插入和删除单行。

将在一个单独的线程中给出一个新行,该线程通过 pyqtsignal 连接到 QAbstractTableModel。 目标是每次给出新的发射时添加一行。如果表格达到 10 行的最大数量,则应添加新发出的行并删除第一行。所以我有一个 maxlen 为 10 个条目的运行表。

目前一切正常,除了删除和添加一行

import sys
import time
from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction, QTableView
from PyQt5.QtCore import QSize, Qt,QAbstractTableModel, pyqtSlot, pyqtSignal, QThread

import sys
import time
from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction, QTableView
from PyQt5.QtCore import QSize, Qt,QAbstractTableModel, pyqtSlot, pyqtSignal, QThread

class Table(QMainWindow):
    def __init__(self):
        QMainWindow.__init__(self)
        self.resize(800, 600)
        self.setMinimumSize(QSize(800, 600))

        self.table = QTableView()
        self.setCentralWidget(self.table)

        toolbar = QToolBar("Toolbar")
        con = QAction("Connect", self)
        con.triggered.connect(self.updateTable)
        discon = QAction("Disconnect", self)
        discon.triggered.connect(self.terminateThread)

        toolbar.addAction(con)
        toolbar.addAction(discon)
        self.addToolBar(toolbar)

    def updateTable(self):
        print("Connect")
        data = [
            ["This", "is", "test", 1],
            ["This", "is", "test", 2],
            ["This", "is", "test", 3],
        ]

        self.model = TableModel(data)
        self.table.setModel(self.model)

        self.thread = QTableThread()
        self.thread.sig1.connect(self.model.addRow)
        self.thread.start()

    def terminateThread(self):
        self.thread1.terminate()

class QTableThread(QThread):
    sig1 = pyqtSignal(list)

    def __init__(self):
        super(QTableThread, self).__init__()
        self.count = 4

    def run(self):
        for i in range(20):
            self.sig1.emit(["This", "is", "test", self.count])
            self.count += 1
            time.sleep(0.5)

class TableModel(QAbstractTableModel):
    def __init__(self, data):
        super(TableModel, self).__init__()
        self._data = data

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self._data[index.row()][index.column()]

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

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

    @pyqtSlot(list)
    def addRow(self,status):
        print(status)
        # What to implement here?


if __name__ == "__main__":
    app = QApplication(sys.argv)
    win = Table()
    win.show()
    sys.exit( app.exec_() )

【问题讨论】:

    标签: python pyqt qtableview qabstracttablemodel


    【解决方案1】:

    我已为您标记了我所做的更改。试试看:

    import sys
    #import time
    from PyQt5.QtWidgets import QApplication, QMainWindow, QToolBar, QAction, QTableView
    from PyQt5.QtCore import (QSize, Qt, QAbstractTableModel, pyqtSlot, pyqtSignal, 
        QThread, QModelIndex)
    
    
    class QTableThread(QThread):
        sig1 = pyqtSignal(list)
    
        def __init__(self):
            super(QTableThread, self).__init__()
            self.count = 4
    
        def run(self):
            for i in range(20):
                self.sig1.emit(["This", "is", "test", self.count])
                self.count += 1
                self.msleep(500)                                            # !!!
    
    
    class TableModel(QAbstractTableModel):
        def __init__(self, _data):
            super(TableModel, self).__init__()
            self._data = _data
    
        def data(self, index, role):
            if role == Qt.DisplayRole:
                return self._data[index.row()][index.column()]
    
        def rowCount(self, index=QModelIndex()):                     # +
            return  0 if index.isValid() else len(self._data)        # +
    
        def columnCount(self, index=QModelIndex()):                  
            return len(self._data[0])
    
    # +++ vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv
        def insertRows(self, new_row, position, rows, parent=QModelIndex()):
            position = (position + self.rowCount()) if position < 0 else position
            start = position
            end = position + rows - 1
    
            if end <= 8:
                self.beginInsertRows(parent, start, end)
                self._data.append(new_row) 
                self.endInsertRows()
                return True
            else:
                self.beginInsertRows(parent, start, end)
                self._data.append(new_row) 
                self.endInsertRows()
                self.removeRows(0, 0)
                return True
    
        def removeRows(self, position, rows, parent=QModelIndex()):
            start, end = position, rows 
            self.beginRemoveRows(parent, start, end)
            del self._data[start:end + 1]
            self.endRemoveRows()
            return True
    # +++ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    
    
    class Table(QMainWindow):
        def __init__(self):
            QMainWindow.__init__(self)
            self.resize(800, 600)
            self.setMinimumSize(QSize(800, 600))
    
            self.table = QTableView()
            self.setCentralWidget(self.table)
    
            toolbar = QToolBar("Toolbar")
            con = QAction("Connect", self)
            con.triggered.connect(self.updateTable)
            discon = QAction("Disconnect", self)
            discon.triggered.connect(self.terminateThread)
    
            toolbar.addAction(con)
            toolbar.addAction(discon)
            self.addToolBar(toolbar)
            
            self.thread = None                                                             # +++
    
        def updateTable(self):
            print("Connect")
            data = [
                ["This", "is", "test", 1],
                ["This", "is", "test", 2],
                ["This", "is", "test", 3],
            ]
            self.model = TableModel(data)
            self.table.setModel(self.model)
    
            self.thread = QTableThread()
    #        self.thread.sig1.connect(self.model.addRow)                                    # ---
            self.thread.sig1.connect(lambda new_row: self.model.insertRows(new_row, -1, 1)) # +++
            self.thread.start()
    
        def terminateThread(self):
            if self.thread and self.thread.isRunning():                                     # +++
                self.thread.terminate()
            
    
    if __name__ == "__main__":
        app = QApplication(sys.argv)
        win = Table()
        win.show()
        sys.exit( app.exec_() )
    

    【讨论】:

    • @progS 你试过了吗?你成功了吗?
    猜你喜欢
    • 2014-05-12
    • 2021-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-03-28
    • 1970-01-01
    • 2016-05-25
    相关资源
    最近更新 更多