5

我创建了一个列出现有配置的模型(假设它列出了“文件”,因为这在这里并不重要)。到目前为止,它在附加到QListView.

例子:

--- ListView ---
- file #1      -
- file #2      -
- file #3      -
- file #4      -
----------------

是否可以使用相同的模型进行动态更新QMenu

就像是:

Menu
-> Submenu #1
-> Submenu #2
-> File-submenu
  -> file #1
  -> file #2
  -> file #3
  -> file #4
-> Submenu #3

简而言之:有什么方法可以根据模型(派生自)创建动态更新QAction的 s 列表(分组到相同的 s中)?QMenuQAbstractListModel

4

5 回答 5

3

不幸的是,没有QMenuView课程,但我在网上找到了这个有希望的实现:(QMenuViewqmenuview.h qmenuview.cpp

于 2011-08-23T14:12:03.103 回答
2

如果您的目标只是使用 中可用的项目文本更新您的菜单操作QAbstractListModel,那么答案是肯定的。

这里有一个方法..

可以使用以下函数获得单个项目的索引。

QModelIndex QAbstractListModel::index ( int row, int column = 0, 
const QModelIndex & parent = QModelIndex() ) const   [virtual]

通过获得的索引,可以通过以下方式获得数据,

 QVariant QModelIndex::data ( int role = Qt::DisplayRole ) const

然后可以通过使用获取索引中可用的文本,

QString QVariant::toString () const

现在使用获得的 QString,您可以向菜单添加操作。

QAction * QMenu::addAction ( const QString & text )

你需要确保的是,你应该能够遍历模型中的所有项目,这样你就可以获得每个项目的索引。希望能帮助到你..

于 2010-06-29T10:16:19.923 回答
1

要回答您的简短问题,是的,有。但是你必须自己写。

最简单的部分是创建 QAbstractListModel 的子类。

困难的部分是当您创建自己的视图时。Qt 将允许您创建自己的视图,就像您要创建自己的模型一样,但是它会变得更加复杂,因为您必须自己处理所有事情。

它完全可以用于特定目的,但它也比我认为你想要的要多得多。因此,正如 Gianni 所说,Qt 的模型视图框架不应该以这种方式使用。

于 2010-06-28T20:46:07.680 回答
0

不可以。根据 Qt 使用的模型视图框架,模型只能与视图一起使用。

于 2010-06-28T16:58:24.193 回答
0

您可以创建一个菜单项并QListView使用QWidgetAction. 当然这个菜单不能有子菜单。下面的例子是用 Python 编写的,但我希望在这种情况下没关系。

在此处输入图像描述

from PyQt5 import QtWidgets, QtCore, QtGui
from PyQt5.QtCore import Qt


class QListViewMenu(QtWidgets.QMenu):
    """
    QMenu with QListView.
    Supports `activated`, `clicked`, `doubleClicked`. `setModel`.
    """
    max_visible_items = 16

    def __init__(self, parent=None):
        super().__init__(parent)
        self.listview = lv = QtWidgets.QListView()
        lv.setFrameShape(lv.NoFrame)
        lv.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        pal = lv.palette()
        pal.setColor(pal.Base, self.palette().color(pal.Window))
        lv.setPalette(pal)
        lv.setEditTriggers(lv.NoEditTriggers)  # disable edit on doubleclick

        act_wgt = QtWidgets.QWidgetAction(self)
        act_wgt.setDefaultWidget(lv)
        self.addAction(act_wgt)

        self.activated = lv.activated
        self.clicked = lv.clicked
        self.doubleClicked = lv.doubleClicked
        self.setModel = lv.setModel

        lv.sizeHint = self.size_hint
        lv.minimumSizeHint = self.size_hint
        lv.mousePressEvent = lambda event: None  # skip
        lv.mouseMoveEvent = lambda event: None  # skip
        lv.mouseReleaseEvent = self.mouse_release_event

    def size_hint(self):
        lv = self.listview
        width = lv.sizeHintForColumn(0)
        width += lv.verticalScrollBar().sizeHint().width()
        if isinstance(self.parent(), QtWidgets.QToolButton):
            width = max(width, self.parent().width())
        visible_rows = min(self.max_visible_items, lv.model().rowCount())
        return QtCore.QSize(width, visible_rows * lv.sizeHintForRow(0))

    def mouse_release_event(self, event):
        if event.button() == Qt.LeftButton:
            idx = self.listview.indexAt(event.pos())
            if idx.isValid():
                self.clicked.emit(idx)
            self.close()
        super(QtWidgets.QListView, self.listview).mouseReleaseEvent(event)


class Form(QtWidgets.QDialog):
    def __init__(self):
        super().__init__()
        words = "ability able about above accept according account across"
        model = QtCore.QStringListModel(words.split())
        # fake icons to take space
        def data(index, role):
            if role == Qt.DecorationRole:
                pixm = QtGui.QPixmap(40, 40)
                pixm.fill(Qt.transparent)
                return QtGui.QIcon(pixm)
            return QtCore.QStringListModel.data(model, index, role)
        model.data = data

        self.btn = btn = QtWidgets.QToolButton(self)
        btn.setText("QListView menu")
        btn.setPopupMode(btn.MenuButtonPopup)
        root_menu = QtWidgets.QMenu(btn)
        menu = QListViewMenu(btn)
        menu.setTitle('submenu')
        menu.setModel(model)
        menu.clicked.connect(self.item_clicked)
        root_menu.addMenu(menu)
        btn.setMenu(root_menu)

    def item_clicked(self, index):
        self.btn.menu().hide()
        print(index.data())

app = QtWidgets.QApplication([])
f = Form()
f.show()
app.exec()
于 2019-05-20T13:02:38.980 回答