CustomMenu
类继承自QMenu
。它的自定义setData()
方法接受一个参数并将其设置为类变量model
。我这样做是因为QToolButton
,QToolMenu
和QAction
不支持模型/视图框架。除了QList-QTable-QTree Views and Trees
之外,我所知道的只有QComboBox
支持model
。
所以问题是:是否可以扩展其他non-model widgets
的功能,以便它们也可以用作driven-by-model
小部件?
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class CustomMenu(QMenu):
def __init__(self):
super(CustomMenu, self).__init__()
self.model=None
def setModel(self, model):
self.model=model
self.pupulate()
def pupulate(self):
for item in self.model.items:
self.addAction(item)
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row1_Column0','Row2_Column0']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, QModelIndex):
return len(self.items)
def columnCount(self, QModelIndex):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[index.row()])
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
self.items[index.row()]=value
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
layout=QVBoxLayout(self)
self.setLayout(layout)
tablemodel=Model(self)
tableView=QTableView()
tableView.horizontalHeader().setStretchLastSection(True)
tableView.setModel(tablemodel)
layout.addWidget(tableView)
combo=QComboBox()
combo.setModel(tablemodel)
layout.addWidget(combo)
toolButton=QToolButton(self)
toolButton.setText('Tool Button')
toolButton.setPopupMode(QToolButton.InstantPopup)
toolButton.setSizePolicy(QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Fixed))
menu=CustomMenu()
menu.setModel(tablemodel)
toolButton.setMenu(menu)
layout.addWidget(toolButton)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class CustomMenuButton(QWidget):
def __init__(self, parent):
super(CustomMenuButton, self).__init__(parent)
self.dataMapper=QDataWidgetMapper()
layout=QVBoxLayout()
self.setLayout(layout)
toolButton=QToolButton(self)
toolButton.setText('Tool Button')
toolButton.setPopupMode(QToolButton.InstantPopup)
self.menu=QMenu(toolButton)
toolButton.setMenu(self.menu)
def setModel(self, model):
self.dataMapper.setModel(model)
for row in range(model.rowCount()):
action=self.menu.addAction('Item')
self.dataMapper.addMapping(action, row)
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row1_Column0','Row2_Column0']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[index.row()])
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
self.items[index.row()]=value
self.dataChanged.emit(index, index)
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
layout=QVBoxLayout(self)
self.setLayout(layout)
tablemodel=Model(self)
tableView=QTableView()
tableView.horizontalHeader().setStretchLastSection(True)
tableView.setModel(tablemodel)
layout.addWidget(tableView)
combo=QComboBox()
combo.setModel(tablemodel)
layout.addWidget(combo)
menuButton=CustomMenuButton(self)
layout.addWidget(menuButton)
menuButton.setModel(tablemodel)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
from PyQt4.QtCore import *
from PyQt4.QtGui import *
import sys, os
class CustomAction(QAction):
dataChanged = pyqtSignal(QModelIndex,QModelIndex)
def __init__(self, name, parent):
super(CustomAction, self).__init__(name, parent)
class CustomMenuButton(QWidget):
def __init__(self, parent):
super(CustomMenuButton, self).__init__(parent)
self.dataMapper=QDataWidgetMapper()
layout=QVBoxLayout()
self.setLayout(layout)
toolButton=QToolButton(self)
toolButton.setText('Tool Button')
toolButton.setPopupMode(QToolButton.InstantPopup)
self.menu=QMenu(toolButton)
toolButton.setMenu(self.menu)
def setModel(self, model):
self.dataMapper.setModel(model)
for row in range(model.rowCount()):
index=model.index(row,0)
itemName=model.data(index, Qt.DisplayRole).toPyObject()
actn=CustomAction(itemName, self.menu)
self.menu.addAction(actn)
self.dataMapper.addMapping(actn, row)
class Model(QAbstractTableModel):
def __init__(self, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.items = ['Row0_Column0','Row1_Column0','Row2_Column0']
def flags(self, index):
return Qt.ItemIsEnabled | Qt.ItemIsSelectable | Qt.ItemIsEditable
def rowCount(self, parent=QModelIndex()):
return len(self.items)
def columnCount(self, parent=QModelIndex()):
return 1
def data(self, index, role):
if not index.isValid(): return QVariant()
if role == Qt.DisplayRole:
return QVariant(self.items[index.row()])
return QVariant()
def setData(self, index, value, role=Qt.EditRole):
if index.isValid():
if role == Qt.EditRole:
self.items[index.row()]=value
self.dataChanged.emit(index, index)
return True
return False
class MyWindow(QWidget):
def __init__(self, *args):
QWidget.__init__(self, *args)
layout=QVBoxLayout(self)
self.setLayout(layout)
tablemodel=Model(self)
tableView=QTableView()
tableView.horizontalHeader().setStretchLastSection(True)
tableView.setModel(tablemodel)
layout.addWidget(tableView)
combo=QComboBox()
combo.setModel(tablemodel)
layout.addWidget(combo)
menuButton=CustomMenuButton(self)
layout.addWidget(menuButton)
menuButton.setModel(tablemodel)
if __name__ == "__main__":
app = QApplication(sys.argv)
w = MyWindow()
w.show()
sys.exit(app.exec_())
答案 0 :(得分:1)
这是QDataWidgetMapper课程的设计目标。以下博客有一个很好的教程,涵盖了如何实现它:http://www.yasinuludag.com/blog/?p=98
编辑:我应该补充说QDataWidgetMapper
适用于QWidget
及其子类,因此QAction
不适用。对于非QWidget
或其子类的类,您可能必须实现自己的自定义模型视图绑定。