使用 QAbstractTableModel 在 pyqts QTableView 中插入和删除行
Insert and remove row in pyqts QTableView using the QAbstractTableModel
如何使用 QAbstractTableModel 在 QTableView 中插入和删除单行。
新行将在一个单独的线程中给出,该线程通过 pyqtsignal 连接到 QAbstractTableModel。
目标是每次给出新的发射时添加一行。如果 Table 达到 10 行的最大值,则应添加新发出的行并删除第一行。所以我有一个 运行 table,最大长度为 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_() )
我为您标记了我所做更改的行。试一试:
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_() )
如何使用 QAbstractTableModel 在 QTableView 中插入和删除单行。
新行将在一个单独的线程中给出,该线程通过 pyqtsignal 连接到 QAbstractTableModel。 目标是每次给出新的发射时添加一行。如果 Table 达到 10 行的最大值,则应添加新发出的行并删除第一行。所以我有一个 运行 table,最大长度为 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_() )
我为您标记了我所做更改的行。试一试:
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_() )