[英]pyqt signal not emitted in QAbstractTableModel
So i'm writing an application and using QTableView
with QAbstractTableModel
to display my data. 因此,我正在编写一个应用程序,并将
QTableView
与QAbstractTableModel
一起使用来显示我的数据。 In each row a checkbox is placed in the first column and when it is checked or unchecked, i want a pyqtsignal CheckBoxValue
be emitted to MyTable
. 在每一行中,复选框都放置在第一列中,当选中或取消选中它时,我希望将pyqtsignal
CheckBoxValue
发出给MyTable
。 But it seems that the connected function self.checkboxchecked
in MyTable
is not called. 但是似乎未调用
MyTable
连接的函数self.checkboxchecked
。 Although I used to use pyqtSignal several times without any issue, i'm stuck here and couldn't solve it out. 尽管我曾经多次使用pyqtSignal,没有任何问题,但我一直呆在这里,无法解决它。
Thank you all for spending time taking care of my question! 谢谢大家花时间解决我的问题!
import operator # used for sorting
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtGui, QtCore
class MyTable(QWidget):
Checkboxcheckvalue = pyqtSignal(bool)
Rowselected = pyqtSignal(int)
doubleClicked = pyqtSignal(int)
def __init__(self, *args):
QWidget.__init__(self, *args)
# setGeometry(x_pos, y_pos, width, height)
# self.setGeometry(70, 150, 1326, 582)
self.dataList = []
self.header = []
self.currentrow = []
self.setWindowTitle("Click on the header to sort table")
self.table_model = MyTableModel(self, self.dataList, self.header)
self.table_view = QTableView()
#self.table_view.setSelectionMode(QAbstractItemView.SingleSelection)
self.table_view.setSelectionMode(QtGui.QAbstractItemView.SingleSelection)
self.table_view.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
# bind cell click to a method reference
self.table_view.clicked.connect(self.showSelection)
self.table_view.clicked.connect(self.selectRow)
self.table_view.doubleClicked.connect(self.doubleclickedaction)
self.table_model.CheckBoxValue.connect(self.checkboxchecked)
self.table_view.setModel(self.table_model)
# enable sorting
self.table_view.setSortingEnabled(True)
layout = QVBoxLayout(self)
layout.addWidget(self.table_view)
self.setLayout(layout)
def update_model(self):
self.table_model = MyTableModel(self, self.dataList, self.header)
self.table_view.setModel(self.table_model)
self.table_view.update()
def findLabelName(self,rowindex):
return self.dataList[rowindex][-1]
def doubleclickedaction(self,index):
self.doubleClicked.emit(index.row())
self.currentrow = index.row()
print ('doubleclicked',self.findLabelName(index.row()))
def checkboxchecked(self,value):
print ('table checkboxchecked',self.currentrow,value)
# self.currentrow = index.row()
if value == True:
self.Checkboxcheckvalue.emit(True)
else:
self.Checkboxcheckvalue.emit(False)
def selectedLabel(self,index):
return self.findLabelName(index.row())
def showSelection(self, item):
cellContent = item.data()
# print(cellContent) # test
sf = "You clicked on {}".format(cellContent)
# display in title bar for convenience
self.setWindowTitle(sf)
def selectRow(self, index):
self.Rowselected.emit(index.row())
self.currentrow = index.row()
print("current row is %d", index.row())
pass
class MyTableModel(QAbstractTableModel):
"""
keep the method names
they are an integral part of the model
"""
CheckBoxValue = pyqtSignal(bool)
def __init__(self, parent, mylist, header, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.mylist = mylist
self.header = header
def setDataList(self, mylist):
self.mylist = mylist
self.layoutAboutToBeChanged.emit()
self.dataChanged.emit(self.createIndex(0, 0), self.createIndex(self.rowCount(0), self.columnCount(0)))
self.layoutChanged.emit()
def rowCount(self, parent):
if self.mylist != []:
return len(self.mylist)
else:
return 0
def columnCount(self, parent):
if self.mylist != []:
return len(self.mylist[0])-1
else:
return 0
def data(self, index, role):
if not index.isValid():
return None
if (index.column() == 0):
value = self.mylist[index.row()][index.column()].text()
else:
value = self.mylist[index.row()][index.column()]
if role == QtCore.Qt.EditRole:
return value
elif role == QtCore.Qt.DisplayRole:
return value
elif role == QtCore.Qt.CheckStateRole:
if index.column() == 0:
if self.mylist[index.row()][index.column()].isChecked():
return QtCore.Qt.Checked
else:
return QtCore.Qt.Unchecked
def headerData(self, col, orientation, role):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.header[col]
return None
def sort(self, col, order):
"""sort table by given column number col"""
if col != 0:
pass
else:
col = -1
self.emit(SIGNAL("layoutAboutToBeChanged()"))
self.mylist = sorted(self.mylist, key=operator.itemgetter(col))
if order == Qt.DescendingOrder:
self.mylist.reverse()
self.emit(SIGNAL("layoutChanged()"))
print 'sorted'
def flags(self, index):
if not index.isValid():
return None
if index.column() == 0:
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsUserCheckable
else:
return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable
def setData(self, index, value, role):
if not index.isValid():
return False
if role == QtCore.Qt.CheckStateRole and index.column() == 0:
if value == QtCore.Qt.Checked:
self.mylist[index.row()][index.column()].setChecked(True)
print('checked',index.row())
self.CheckBoxValue.emit(True)
else:
self.mylist[index.row()][index.column()].setChecked(False)
print('unchecked',index.row())
self.CheckBoxValue.emit(False)
self.dataChanged.emit(index, index)
return True
if __name__ == '__main__':
app = QApplication([])
header = ['name', 'type', 'segment', 'exit', 'entry']
dataList = [
[QtGui.QCheckBox('line9'), 'line', '058176', '01', '1705','line9'],
[QtGui.QCheckBox('line3'), 'line', '058176', '02', '1705','line3'],
[QtGui.QCheckBox('line6'), 'line', '058176', '03', '1705','line6'],
[QtGui.QCheckBox('line1'), 'line', '058176', '04', '1705','line'],
[QtGui.QCheckBox('line4'), 'line', '058176', '01', '1705','line4'],
[QtGui.QCheckBox('area4'), 'area', '058176', '02', '1705','area4'],
[QtGui.QCheckBox('area2'), 'area', '058176', '02', '1705','area2'],
[QtGui.QCheckBox('area8'), 'area', '058176', '01', '1705','area8'],
]
win = MyTable()
win.dataList = dataList
win.header = header
win.update_model()
win.show()
app.exec_()
In your case you have created a table_model in the MyTable constructor, and with that object you have made the connection, but later in the update_model method you have created a new model so the previous model has been deleted and its connections as well. 在您的情况下,您已在MyTable构造函数中创建了table_model,并与该对象建立了连接,但是稍后在update_model方法中创建了新模型,因此先前的模型及其连接也已删除。
def update_model(self):
self.table_model = MyTableModel(self, self.dataList, self.header)
self.table_view.setModel(self.table_model)
self.table_model.CheckBoxValue.connect(self.checkboxchecked)
self.table_view.update()
Although I prefer to update the model, instead of creating a new model for it, I would create a method to update the data: 尽管我更喜欢更新模型,而不是为其创建新模型,但我将创建一种方法来更新数据:
class MyTableModel(QAbstractTableModel):
"""
keep the method names
they are an integral part of the model
"""
CheckBoxValue = pyqtSignal(bool)
def __init__(self, parent, mylist, header, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.mylist = mylist
self.header = header
def update_model(self, mylist, header):
self.beginResetModel()
self.mylist = mylist
self.header = header
self.endResetModel()
[...]
and in the update_model of the Table: 并在表的update_model中:
class MyTable(QWidget):
[...]
def update_model(self):
self.table_model.update_model(self.dataList, self.header)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.