質問

既存の構成をリストするモデルを作成しました(「ファイル」をリストするとしましょう。これは実際には問題ではないためです)。これまでのところ、それは 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

要するに、Dynamicalyの更新のリストを作成する方法はありますか QActionS(同じにグループ化されています QMenu)aに依存します モデル (に由来する QAbstractListModel) ?

役に立ちましたか?

解決

あなたの目的が、で利用可能なアイテムテキストでメニューのactonsを更新することだけである場合 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 )

確かにしなければならないのは、モデル内のすべてのアイテムを通過できるように、すべてのアイテムのインデックスを取得できるようにすることです。それが役に立てば幸い..

他のヒント

残念ながら、いません QMenuView クラスですが、ネット上のこの有望な実装を見つけました。 QMenuView (QMENUVIEW.H, qmenuview.cpp).

あなたの短い質問に答えるために、はい、あります。しかし、あなたはそれを自分で書かなければなりません。

簡単な部分は、QabstractListModelのサブクラスを作成することです。

難しい部分は、独自のビューを作成するときです。 QTは、独自のモデルを作成するように、独自のビューを作成できますが、処理する必要があるため、はるかに複雑になります。 すべての あなた自身。

特定の目的のために完全に実行可能ですが、あなたが望んでいるよりもはるかに多くの仕事でもあります。したがって、ジャンニが言っていたように、QTのモデルビューフレームワークはこのように使用することを意図していません。

いいえ。モデルはビューでのみ使用できます。 モデルビュー QTが使用するフレームワーク。

メニュー項目を作成して配置できます QListView それを使用して QWidgetAction. 。もちろん、このメニューはサブメナスを持つことはできません。以下の例はPythonにありますが、この場合は問題ではないことを願っています。

enter image description here

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()
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top