在Qt中,`setContextMenuPolicy()` 是一个相当通用的方法,几乎所有的继承自 `QWidget` 或其派生类的图形用户界面控件都可以使用该方法来设置它们的上下文菜单策略。这意味着,包括但不限于以下常见的Qt GUI控件都能使用 `setContextMenuPolicy()` 来控制其右键菜单行为:
- QPushButton
- QLineEdit
- QTextEdit
- QTreeView
- QTableView
- QTableWidget
- QListWidget
- QGraphicsView
- QComboBox
- QLabel
- QMainWindow
- QMenuBar
- QToolBar
- QStatusBar
- QWidget本身及其自定义子类
通过调用 `setContextMenuPolicy(Qt::ContextMenuPolicy policy)` 函数,可以设定控件在用户右击时的行为,比如是否启用默认上下文菜单、禁用上下文菜单,或者开启自定义上下文菜单(通过 `Qt::CustomContextMenu` 策略并连接 `customContextMenuRequested(const QPoint &pos)` 信号)。
在Qt框架中,`setContextMenuPolicy()` 是一个用于设置控件上下文菜单策略的成员函数,它允许你定义当用户在某个控件上执行右键单击(即上下文菜单请求)时控件如何响应。这个函数的常见用法如下:
```cpp
void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
```
其中:
- `policy`:它是 `Qt::ContextMenuPolicy` 枚举类型的一个值,决定了控件如何处理上下文菜单事件。
以下是 `Qt::ContextMenuPolicy` 枚举类型的几个常见值及其含义:
1. **Qt::NoContextMenu**:
禁止上下文菜单,事件不会被控件处理,可能会被其父控件处理。
2. **Qt::PreventContextMenu**:
同样禁止上下文菜单,但与 `NoContextMenu` 不同的是,它不将事件传播给父控件,而是完全阻止任何上下文菜单的弹出。
3. **Qt::DefaultContextMenu**:
使用控件的默认上下文菜单处理,通常是调用 `contextMenuEvent()` 函数来处理上下文菜单事件。
4. **Qt::ActionsContextMenu**:
控件将显示其关联动作(actions)作为上下文菜单的内容,可以通过 `QWidget::addAction()` 添加的动作会被包含在这个菜单中。
5. **Qt::CustomContextMenu**:
当用户右击控件时,控件会发出 `customContextMenuRequested(QPoint pos)` 信号,而不显示默认的菜单。开发者需要连接这个信号到一个槽函数,在槽函数中创建并显示自定义的上下文菜单。
示例代码:```cpp
// 假设有一个QWidget实例名为myWidget
myWidget->setContextMenuPolicy(Qt::CustomContextMenu); // 设置为自定义上下文菜单
// 连接信号
connect(myWidget, &QWidget::customContextMenuRequested,
this, &MyClass::showCustomContextMenu); // MyClass是包含此代码的类
// 定义槽函数
void MyClass::showCustomContextMenu(const QPoint &pos)
{
QMenu menu(this);
QAction *action1 = menu.addAction("Action 1");
QAction *action2 = menu.addAction("Action 2");
// 连接动作的触发信号
connect(action1, &QAction::triggered, this, &MyClass::onAction1Clicked);
connect(action2, &QAction::triggered, this, &MyClass::onAction2Clicked);
menu.exec(myWidget->mapToGlobal(pos)); // 在鼠标点击的位置显示菜单
}
通过这种方式,你可以根据不同的需求灵活地配置Qt控件的上下文菜单行为。
实例:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void slotTableMenu(const QPoint &pos); //表格右键菜单
void slotActionCopy(bool checked); //复制
void slotActionSave(bool checked); //另存为
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDir>
#include <QDateTime>
#include <QClipboard>
#include <QFileDialog>
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->tableWidget->setContextMenuPolicy(Qt::CustomContextMenu);
connect(ui->tableWidget, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(slotTableMenu(const QPoint&)));
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::slotTableMenu(const QPoint &pos)
{
QMenu menu;
menu.addAction(QStringLiteral("复制"), this, SLOT(slotActionCopy(bool)));
menu.addAction(QStringLiteral("另存为"), this, SLOT(slotActionSave(bool)));
menu.exec(QCursor::pos());
}
//复制截图到剪切板
void MainWindow::slotActionCopy(bool checked)
{
QString strFile = QCoreApplication::applicationDirPath() + "\\ScreenShot\\Data_";
strFile = strFile + QDateTime::currentDateTime().toString("yyyyMMddHHmmss") + ".png";
QPixmap pix = QPixmap::grabWidget(ui->tableWidget);
QApplication::clipboard()->setPixmap(pix);
}
//截图另存为文件
void MainWindow::slotActionSave(bool checked)
{
//默认保存路径为当前应用程序路径下的ScreenShot文件夹,如果没有就新建该文件夹
QString strDir = QCoreApplication::applicationDirPath() + "\\ScreenShot";
QDir dir(strDir);
if(!dir.exists())
{
dir.mkdir(strDir);
}
QString strFile = strDir + "\\数据快照" + QDateTime::currentDateTime().toString("yyyyMMddHHmmss") + ".png";
QPixmap pix = QPixmap::grabWidget(ui->tableWidget);
QString fileName = QFileDialog::getSaveFileName(this,"保存图片",strFile,"PNG (*.png);;BMP (*.bmp);;JPEG (*.jpg *.jpeg)");
if (!fileName.isNull())
{
pix.save(fileName);
}
}
图示: