首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計綜合問答

Qt5 QListView 右鍵選單實作:自訂模型、委派與 ContextMenuEvent 完整範例

     編輯:程式設計綜合問答

核心步驟

  1. 啟用 setContextMenuPolicy(Qt::CustomContextMenu)。
  2. 連接 customContextMenuRequested(const QPoint&) 信號。
  3. 槽函數中用 indexAt(pos) 獲取點擊項模型索引。
  4. 建立 QMenu、添加 QAction、連接觸發槽。
  5. exec(mapToGlobal(pos)) 彈出選單。

最小可行範例


// MyListView.h
class MyListView : public QListView {
    Q_OBJECT
public:
    explicit MyListView(QWidget* parent = nullptr);
protected:
    void contextMenuEvent(QContextMenuEvent* event) override; // 或用信號槽
};

// MyListView.cpp
MyListView::MyListView(QWidget* parent) : QListView(parent) {
    setContextMenuPolicy(Qt::CustomContextMenu);
    connect(this, &QListView::customContextMenuRequested, this, &MyListView::showContextMenu);
    setModel(new QStringListModel({"Item 1", "Item 2", "Item 3"}, this));
}

void MyListView::showContextMenu(const QPoint& pos) {
    QModelIndex idx = indexAt(pos);
    if (!idx.isValid()) return; // 點擊空白處不顯示

    QMenu menu(this);
    QAction* actDelete = menu.addAction("刪除");
    QAction* actEdit   = menu.addAction("編輯");

    connect(actDelete, &QAction::triggered, [this, idx](){
        QStringListModel* m = qobject_cast(model());
        QStringList list = m->stringList();
        list.removeAt(idx.row());
        m->setStringList(list);
    });
    connect(actEdit, &QAction::triggered, [this, idx](){
        bool ok;
        QString text = QInputDialog::getText(this, "編輯", "新內容:", QLineEdit::Normal, idx.data().toString(), &ok);
        if (ok && !text.isEmpty()) {
            QStringListModel* m = qobject_cast(model());
            QStringList list = m->stringList();
            list[idx.row()] = text;
            m->setStringList(list);
        }
    });

    menu.exec(viewport()->mapToGlobal(pos));
}

進階:自訂模型 (QAbstractListModel) 支援圖標、複雜資料


class MyModel : public QAbstractListModel {
    QVector items;
public:
    enum Roles { NameRole = Qt::UserRole + 1, IconRole };
    QVariant data(const QModelIndex& index, int role) const override {
        if (!index.isValid()) return {};
        const auto& item = items[index.row()];
        if (role == NameRole) return item.name;
        if (role == IconRole) return item.icon;
        return {};
    }
    QHash roleNames() const override {
        return {{NameRole, "name"}, {IconRole, "icon"}};
    }
    // insertRows, removeRows, setData 等增刪改實作...
};

QML/Delegate 中即可用 model.name、model.icon 綁定。

參考資源

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved