【发布时间】:2020-11-16 01:25:17
【问题描述】:
我有一个 QTableView,它有一列包含 True/False 值。要更改此列中的值,我使用 QDataWidgetMapper 复选框。
我希望在单击复选框后立即更改值。通常在复选框失去焦点后进行更改(换句话说,您需要在应用程序的其他地方进行额外的点击)。
我曾尝试这样做:checkBox.stateChanged.connect(lambda: data_mapper.submit()),但我不喜欢使用这种方法发出太多信号:首先它发出所有映射的信号项目已更改,并且在复选框失去焦点后 - 仅更改一项的信号。
所以目标是在单击复选框后立即更新模型并且只发出一个信号。
代码:
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
class Mainwindow(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.table = QtWidgets.QTableView()
self.widget_1 = Widget_1(self)
self.layout_1 = QtWidgets.QHBoxLayout()
self.layout_1.addWidget(self.table)
self.layout_1.addWidget(self.widget_1)
self.setLayout(self.layout_1)
headers = ['State', 'Prorerty_1', 'Prorerty_2']
data = [
[True, '1', '2'],
[False, '3', '4']
]
self.model = ListModel(data, headers)
self.table.setModel(self.model)
self.table.setSelectionBehavior(self.table.SelectRows)
self.table.clicked.connect(self.set_data_mapper)
self.model.dataChanged.connect(lambda value: print(value.row(), value.column(), value.data()))
def set_data_mapper(self):
position = self.table.selectionModel().selectedIndexes()[0].row()
self.widget_1.data_mapper.setModel(self.model)
self.widget_1.data_mapper.addMapping(self.widget_1.checkBox, 0)
self.widget_1.data_mapper.addMapping(self.widget_1.lineEdit, 1)
self.widget_1.data_mapper.setCurrentIndex(position)
self.widget_1.checkBox.stateChanged.connect(lambda: self.widget_1.data_mapper.submit())
class Widget_1(QtWidgets.QWidget):
def __init__(self, parent):
super().__init__()
self.parent = parent
self.layout_1 = QtWidgets.QGridLayout()
self.state = QtWidgets.QLabel('State')
self.checkBox = QtWidgets.QCheckBox()
self.property = QtWidgets.QLabel('Prop.1')
self.lineEdit = QtWidgets.QLineEdit()
self.layout_1.addWidget(self.state, 0, 0)
self.layout_1.addWidget(self.checkBox, 0, 1)
self.layout_1.addWidget(self.property, 1, 0)
self.layout_1.addWidget(self.lineEdit, 1, 1)
self.setLayout(self.layout_1)
self.data_mapper = QtWidgets.QDataWidgetMapper()
class ListModel(QtCore.QAbstractTableModel):
def __init__(self, data_list = [[]], headers = [], parent = None):
super(ListModel, self).__init__()
self.data_list = data_list
self.headers = headers
def rowCount(self, parent):
return len(self.data_list)
def columnCount(self, parent):
return len(self.headers)
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
row = index.row()
column = index.column()
value = self.data_list[row][column]
return value
if role == QtCore.Qt.EditRole:
row = index.row()
column = index.column()
value = self.data_list[row][column]
return value
if role == QtCore.Qt.FontRole:
if index.column() == 0:
boldfont = QtGui.QFont()
boldfont.setBold(True)
return boldfont
def setData(self, index, value, role = QtCore.Qt.EditRole):
if role == QtCore.Qt.EditRole:
row = index.row()
column = index.column()
self.data_list[row][column] = value
self.dataChanged.emit(index, index)
return True
return False
def headerData(self, section, orientation, role):
if role == QtCore.Qt.DisplayRole:
if orientation == QtCore.Qt.Horizontal:
return self.headers[section]
if __name__ == '__main__':
app = QtWidgets.QApplication([])
application = Mainwindow()
application.show()
sys.exit(app.exec())
【问题讨论】:
标签: python python-3.x pyqt pyqt5 datamapper