当 QListview 项的复选框更改时发出信号
Emit Signal when QListview item's checkbox changes
如何在 qlistview 项目的复选框更改时发出信号?理想情况下,发出的信号会有某种指向发生变化的项目的指针,这样我就可以在 PySide 中采取相应的行动。
import os
import sys
import json
from PySide import QtGui, QtCore
class MegaMergeWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
super(MegaMergeWindow, self).__init__(*args, **kwargs)
self.TITLE = 'Mega Merge'
self.VERSION = '1.0.0'
self.setWindowTitle(self.TITLE + ' | ' + self.VERSION)
self.resize(350,500)
# vars
self.user_folder = os.path.join(os.getenv('LOCALAPPDATA'), 'MegaMerge')
# controls
self.ui_files = QtGui.QListView()
self.ui_files.setModel(QtGui.QStandardItemModel())
self.ui_files.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.ui_merge = QtGui.QPushButton('Merge')
main_layout = QtGui.QVBoxLayout()
main_layout.addWidget(self.ui_files)
main_layout.addWidget(self.ui_merge)
main_widget = QtGui.QWidget()
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
# signals
self.ui_merge.clicked.connect(self.merge_clicked)
self.populate_files()
def populate_files(self, files=[], clear=False):
model = self.ui_files.model()
if clear:
model.clear()
files = ['Doug','Kevin','Amy','Melissa','John']
for f in files:
name = os.path.basename(f)
item = QtGui.QStandardItem(name)
item.setData(f, role=QtCore.Qt.UserRole)
item.setCheckable(True)
item.setCheckState(QtCore.Qt.Checked)
model.appendRow(item)
model.sort(0, QtCore.Qt.AscendingOrder)
def collect_paths(self):
files = []
model = self.ui_files.model()
for index in range(model.rowCount()):
item = model.item(index)
if item.checkState() == QtCore.Qt.Checked:
files.append(item.text())
return files
def merge_files(self, files=[]):
print files
def merge_clicked(self):
files = self.collect_paths()
print files
def main():
app = QtGui.QApplication(sys.argv)
ex = MegaMergeWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在Qt4中没有信号指示是否检查QCheckBox
或QAbstractItemView
,只是在Qt5中修改了dataChanged
信号以发送被修改的角色,因此区分检查是否被更改。
在 Qt4 中,有几种方法可以创建该信号,一种方法是使用委托来跟踪该角色的变化,如下所示:
class StyledItemDelegate(QtGui.QStyledItemDelegate):
checked = QtCore.Signal(QtCore.QModelIndex, int)
def editorEvent(self, event, model, option, index):
if model.flags(index) & QtCore.Qt.ItemIsUserCheckable:
# before the change
last_value = index.data(QtCore.Qt.CheckStateRole)
value = QtGui.QStyledItemDelegate.editorEvent(self, event, model, option, index)
if model.flags(index) & QtCore.Qt.ItemIsUserCheckable:
# after the change
new_value = index.data(QtCore.Qt.CheckStateRole)
if last_value != new_value:
self.checked.emit(index, new_value)
return value
class MegaMergeWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
[...]
# controls
self.ui_files = QtGui.QListView()
self.ui_files.setModel(QtGui.QStandardItemModel())
self.ui_files.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
delegate = StyledItemDelegate()
delegate.checked.connect(self.on_checked)
self.ui_files.setItemDelegate(delegate)
[...]
def on_checked(self, index, state):
text = "Checked" if state == QtCore.Qt.Checked else "UnChecked"
item = self.ui_files.model().itemFromIndex(index)
print(item, item.data())
print(index, index.data())
print(state)
print(text)
如何在 qlistview 项目的复选框更改时发出信号?理想情况下,发出的信号会有某种指向发生变化的项目的指针,这样我就可以在 PySide 中采取相应的行动。
import os
import sys
import json
from PySide import QtGui, QtCore
class MegaMergeWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
super(MegaMergeWindow, self).__init__(*args, **kwargs)
self.TITLE = 'Mega Merge'
self.VERSION = '1.0.0'
self.setWindowTitle(self.TITLE + ' | ' + self.VERSION)
self.resize(350,500)
# vars
self.user_folder = os.path.join(os.getenv('LOCALAPPDATA'), 'MegaMerge')
# controls
self.ui_files = QtGui.QListView()
self.ui_files.setModel(QtGui.QStandardItemModel())
self.ui_files.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.ui_merge = QtGui.QPushButton('Merge')
main_layout = QtGui.QVBoxLayout()
main_layout.addWidget(self.ui_files)
main_layout.addWidget(self.ui_merge)
main_widget = QtGui.QWidget()
main_widget.setLayout(main_layout)
self.setCentralWidget(main_widget)
# signals
self.ui_merge.clicked.connect(self.merge_clicked)
self.populate_files()
def populate_files(self, files=[], clear=False):
model = self.ui_files.model()
if clear:
model.clear()
files = ['Doug','Kevin','Amy','Melissa','John']
for f in files:
name = os.path.basename(f)
item = QtGui.QStandardItem(name)
item.setData(f, role=QtCore.Qt.UserRole)
item.setCheckable(True)
item.setCheckState(QtCore.Qt.Checked)
model.appendRow(item)
model.sort(0, QtCore.Qt.AscendingOrder)
def collect_paths(self):
files = []
model = self.ui_files.model()
for index in range(model.rowCount()):
item = model.item(index)
if item.checkState() == QtCore.Qt.Checked:
files.append(item.text())
return files
def merge_files(self, files=[]):
print files
def merge_clicked(self):
files = self.collect_paths()
print files
def main():
app = QtGui.QApplication(sys.argv)
ex = MegaMergeWindow()
ex.show()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
在Qt4中没有信号指示是否检查QCheckBox
或QAbstractItemView
,只是在Qt5中修改了dataChanged
信号以发送被修改的角色,因此区分检查是否被更改。
在 Qt4 中,有几种方法可以创建该信号,一种方法是使用委托来跟踪该角色的变化,如下所示:
class StyledItemDelegate(QtGui.QStyledItemDelegate):
checked = QtCore.Signal(QtCore.QModelIndex, int)
def editorEvent(self, event, model, option, index):
if model.flags(index) & QtCore.Qt.ItemIsUserCheckable:
# before the change
last_value = index.data(QtCore.Qt.CheckStateRole)
value = QtGui.QStyledItemDelegate.editorEvent(self, event, model, option, index)
if model.flags(index) & QtCore.Qt.ItemIsUserCheckable:
# after the change
new_value = index.data(QtCore.Qt.CheckStateRole)
if last_value != new_value:
self.checked.emit(index, new_value)
return value
class MegaMergeWindow(QtGui.QMainWindow):
def __init__(self, *args, **kwargs):
[...]
# controls
self.ui_files = QtGui.QListView()
self.ui_files.setModel(QtGui.QStandardItemModel())
self.ui_files.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
delegate = StyledItemDelegate()
delegate.checked.connect(self.on_checked)
self.ui_files.setItemDelegate(delegate)
[...]
def on_checked(self, index, state):
text = "Checked" if state == QtCore.Qt.Checked else "UnChecked"
item = self.ui_files.model().itemFromIndex(index)
print(item, item.data())
print(index, index.data())
print(state)
print(text)