QT实现右键快捷菜单

QWidget及其子类都可有右键菜单,因为QWidget有以下两个与右键菜单有关的函数:

Qt::ContextMenuPolicy contextMenuPolicy () const

void setContextMenuPolicy ( Qt::ContextMenuPolicy policy )

Qt::ContextMenuPolicy 枚举类型包括:Qt::DefaultContextMenu, Qt::NoContextMenu, Qt::PreventContextMenu, Qt::ActionsContextMenu, and Qt::CustomContextMenu。

使用方式如下:


1)默认是Qt::DefaultContextMenu。
它是利用右键菜单事件contextMenuEvent()来处理(which means the contextMenuEvent() handler is called)。就是要重写contextMenuEvent( QContextMenuEvent * event )函数。


2)使用Qt::CustomContextMenu。
它是发出QWidget::customContextMenuRequested信号,注重仅仅只是发信号,意味着要自己写显示右键菜单的slot。
这个信号是 QWidget唯一与右键菜单有关的信号(也是自有的唯一信号),同时也是很轻易被忽略的signal:

void customContextMenuRequested ( const QPoint & pos )

该信号的发出条件是:用户请求contextMenu(常规就是鼠标右击啦)且同时被击的widget其contextMenuPolicy又是 Qt::CustomContextMenu。
注重:pos是该widget接收右键菜单事件的位置,一般是在该部件的坐标系中。但是对于QAbstratScrollArea及其子类例外,是对应着其视口viewport()的坐标系。如常用的QTableView、QHeaderView就是QAbstratScrollArea的子类。
因为仅发信号,所以需自己写显示右键菜单的slot来响应,例如一个表格(QTableView类型)表头的显示右键菜单槽:
datatable->horizontalHeader()->setContextMenuPolicy(Qt::CustomContextMenu);
connect(datatable->horizontalHeader(), SIGNAL(customContextMenuRequested(const QPoint&)), 
        this, SLOT(show_contextmenu(const QPoint&)));//this是datatable所在窗口
QMenu *cmenu = NULL;
show_contextmenu(const QPoint& pos)
{
    if(cmenu)//保证同时只存在一个menu,及时释放内存
    {
        delete cmenu;
        cmenu = NULL;
    }
    QMenu cmenu = new QMenu(datatable->horizontalHeader());
    
    QAction *ascendSortAction = cmenu->addAction("升序");
    QAction *descendSortAction = cmenu->addAction("降序");
    QAction *filterAction = cmenu->addAction("过滤");
    QAction *reshowAction = cmenu->addAction("重载");
    
    connect(ascendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_ascend()));
    connect(descendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_descend()));
    connect(filterAction, SIGNAL(triggered(bool)), this, SLOT(show_filter_dlg()));
    connect(reshowAction, SIGNAL(triggered(bool)), this, SLOT(reshow_data()));
    
    cmenu->exec(QCursor::pos());//在当前鼠标位置显示
    //cmenu->exec(pos)是在viewport显示
}

也可先做好cmenu,好处是始终使用一个:
    QMenu cmenu = new QMenu(datatable->horizontalHeader());
    
    QAction *ascendSortAction = cmenu->addAction("升序");
    QAction *descendSortAction = cmenu->addAction("降序");
    QAction *filterAction = cmenu->addAction("过滤");
    QAction *reshowAction = cmenu->addAction("重载");
    
    connect(ascendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_ascend()));
    connect(descendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_descend()));
    connect(filterAction, SIGNAL(triggered(bool)), this, SLOT(show_filter_dlg()));
    connect(reshowAction, SIGNAL(triggered(bool)), this, SLOT(reshow_data()));
show_contextmenu(const QPoint& pos)
{
    if(cmenu)
    {
        cmenu->exec(QCursor::pos());
    }
}


3)使用 Qt::ActionsContextMenu。
把部件的所有 action即QWidget::actions()作为context menu显示出来。
还是上面的例子,要在表格(QTableView类型)表头显示右键菜单:
        QAction *ascendSortAction = new QAction("升序", this);
        QAction *descendSortAction = new QAction("降序", this);
        QAction *filterAction = new QAction("过滤", this);
        QAction *unfilterAction = new QAction("取消过滤", this);
    
        connect(ascendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_ascend()));
        connect(descendSortAction, SIGNAL(triggered(bool)), this, SLOT(sort_descend()));
        connect(filterAction, SIGNAL(triggered(bool)), this, SLOT(filter_table()));
        connect(unfilterAction, SIGNAL(triggered(bool)), this, SLOT(unfilter_table()));
    
        datatable->horizontalHeader()->addAction(ascendSortAction);
        datatable->horizontalHeader()->addAction(descendSortAction);
        datatable->horizontalHeader()->addAction(filterAction);
        datatable->horizontalHeader()->addAction(unfilterAction);
         
        datatable->horizontalHeader()->setContextMenuPolicy(Qt::ActionsContextMenu);

另外两个就是不显示context menu了:
Qt::NoContextMenu
    the widget does not feature a context menu, context menu handling is deferred to the widget's parent.
    
Qt::PreventContextMenu
    the widget does not feature a context menu, and in contrast to NoContextMenu, the handling is not deferred to the widget's parent. This means that all right mouse button events are guaranteed to be delivered to the widget itself through mousePressEvent(), and mouseReleaseEvent().

补充:
    使用Qt::ActionsContextMenu比较简洁,但是假如需要根据当前菜单弹出的位置来定义不同菜单,或者像上个例子,在表格(QTableView类型)表头显示右键菜单时,我需要知道是哪一列表头被点击,从而在后来调用sort_ascend()排序函数时能够根据不同列进行不同排序策略,那么Qt::ActionsContextMenu就做不到了。
    这种需要捕捉弹出位置的情况只好用Qt::ActionsContextMenu了,customContextMenuRequested ( const QPoint & pos )信号返回点击位置pos(在表头视口坐标系中位置),然后表头即可调用logicalIndexAt(pos)函数得到被点击section对应的 index即被点击部分的列号,然后存下来可供后面action激活的排序槽使用。
show_contextmenu(const QPoint& pos)
{
    //get related column of headerview
    contextmenu_column = datatable->horizontalHeader()->logicalIndexAt(pos);

    //show contextmenu
    if(cmenu)
    {
        cmenu->exec(QCursor::pos());
    }
}

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 在 Qt 中使用右键菜单来显示输入框可以这样做: 1. 在你的窗口类中重新实现 `contextMenuEvent` 事件处理程序。 ``` void MainWindow::contextMenuEvent(QContextMenuEvent *event) { // 创建右键菜单 QMenu menu(this); // 在菜单中添加一个 QAction QAction *inputAction = menu.addAction("输入框"); // 在菜单中显示输入框 QInputDialog inputDialog; connect(inputAction, &QAction::triggered, &inputDialog, &QInputDialog::open); // 在鼠标位置显示菜单 menu.exec(event->globalPos()); } ``` 2. 在你的窗口类中添加一个槽函数来处理输入框的输入。 ``` void MainWindow::onInputDialogAccepted(const QString &text) { // 在这里处理输入框中的文本 qDebug() << "输入的文本: " << text; } ``` 3. 在创建输入框时连接槽函数。 ``` QInputDialog inputDialog; connect(&inputDialog, &QInputDialog::accepted, this, &MainWindow::onInputDialogAccepted); ``` 完整代码如下: ``` #include <QMenu> #include <QInputDialog> void MainWindow::contextMenuEvent(QContextMenuEvent *event) { QMenu menu(this); QAction *inputAction = menu.addAction("输入框"); connect(inputAction, &QAction::triggered, this, &MainWindow::showInputDialog); menu.exec(event->globalPos()); } void MainWindow::showInputDialog() { QInputDialog inputDialog; connect(&inputDialog, &QInputDialog::accepted, this, &MainWindow::onInputDialogAccepted); inputDialog.open(); } void MainWindow::onInputDialogAccepted(const QString &text) { qDebug() << "输入的文本: " << text; } ``` ### 回答2: 在QT实现右键菜单点击出现输入框的方法如下: 1. 首先,在需要添加右键菜单的组件(例如QWidget、QLineEdit等)的构造函数中,调用setContextMenuPolicy(Qt::CustomContextMenu)函数,设置为自定义右键菜单。 2. 然后,重写该组件的contextMenuEvent()函数。该函数会在用户右键点击组件时触发。在该函数中,创建一个QMenu对象作为右键菜单,然后添加一个QAction对象到菜单中。 3. 为QAction对象关联一个槽函数,该槽函数会在用户点击右键菜单中的该项时被调用。在槽函数中,创建一个QInputDialog输入对话框,用于用户输入内容。 4. 通过调用QInputDialog的exec()函数,显示输入对话框,并获取用户输入的内容。可以使用getText()、getInt()、getItem()等函数根据需要获取不同类型的输入。 下面是一个示例代码: // mywidget.h #ifndef MYWIDGET_H #define MYWIDGET_H #include <QWidget> #include <QMenu> #include <QInputDialog> class MyWidget : public QWidget { Q_OBJECT public: MyWidget(QWidget *parent = nullptr); protected: void contextMenuEvent(QContextMenuEvent *event) override; private slots: void showInputDialog(); private: QMenu *menu; }; #endif // MYWIDGET_H // mywidget.cpp #include "mywidget.h" MyWidget::MyWidget(QWidget *parent) : QWidget(parent) { setContextMenuPolicy(Qt::CustomContextMenu); menu = new QMenu(this); QAction *inputAction = new QAction("输入框", this); connect(inputAction, &QAction::triggered, this, &MyWidget::showInputDialog); menu->addAction(inputAction); } void MyWidget::contextMenuEvent(QContextMenuEvent *event) { menu->exec(event->globalPos()); } void MyWidget::showInputDialog() { bool ok; QString text = QInputDialog::getText(this, tr("输入框"), tr("请输入内容:"), QLineEdit::Normal, QString(), &ok); if (ok && !text.isEmpty()) { // 处理用户输入的内容 } } 在上述示例代码中,自定义的QWidget派生类MyWidget实现右键菜单功能。在构造函数中,创建一个QMenu对象,并添加一个QAction对象到菜单中。QAction对象的触发信号与槽函数showInputDialog()关联。在showInputDialog()函数中,创建一个QInputDialog对象,并调用exec()函数显示输入对话框。用户输入内容后,可以根据需要进行处理。 ### 回答3: 在QT实现右键菜单点击出现输入框,可以通过以下步骤进行: 1. 创建一个QWidget或者QMainWindow的派生类,作为主窗口。 2. 在主窗口中,重写其右键菜单事件函数contextMenuEvent(QContextMenuEvent *event),该函数在右键点击时会被调用。 3. 在重写的contextMenuEvent函数中,创建一个QMenu对象作为右键菜单。 4. 在QMenu对象中,使用addAction函数添加一个QAction对象,该对象表示右键菜单中的一个选项。 5. 为QAction对象的triggered()信号关联一个槽函数,该槽函数在右键菜单被点击时被执行。 6. 在槽函数中,创建一个QInputDialog对象,作为输入框。 7. 设置QInputDialog的标题、提示信息等属性。 8. 调用QInputDialog的exec()函数显示输入框,并通过返回值判断用户的操作。 9. 根据用户的操作,可以使用QInputDialog的textValue()函数获取用户输入的文本内容。 10. 根据需求,做相应的处理,比如将输入的内容显示在界面上或者进行其他操作。 最后,编译运行程序,当在主窗口右键点击时,会弹出右键菜单,点击菜单中的选项后,会出现一个输入框供用户输入内容。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值