目录
Qt 中用于处理项数据(item data)的组件有两类:一类是 Item Views 组件,包括 QListView、 QTreeView、QTableView 等;另一类是 Item Widgets 组件,包括 QListWidget、QTreeWidget、 QTableWidget 等。Item Views 组件用于模型/视图结构。
Item Widgets组件使用起来稍微复杂一点。它们直接将数据存储在每一个项里,例如, QListWidget 的每一行是一个项,QTreeWidget 的每个节点是一个项,QTableWidget 的每一个单元格是一个项。一个项存储了文字、文字的格式定义、图标、用户数据等内容。
一. 窗口界面可视化设计
1.界面布局和设计方法
本示例的窗口类从 QMainWindow 继承而来,使用了混合式 UI 设计,右图为在 Qt Designer 里设计完成的窗体界面,左图为经代码调整后的最后效果。
在可视化设计界面时,我们删除了窗体上的菜单栏和状态栏,只保留了工具栏。工作区左侧是一个工具箱,创建了 3 个页面,工作区右侧是一个分组框,这两个组件使用了水平分割布局。
QToolButton 有一个 setDefaultAction()函数,可以使按钮与 Action 关联,按钮的文字、图标、toolTip 等属性都将自动从关联的 Action 复制而来。点击一个工具按钮时就会运行关联 Action 的 triggered()信号的槽函数,效果与点击工具栏上的按钮一样。实际上,工具栏上的按钮就是根据 Action 自动创建的工具按钮。
在 Qt Designer 里并不能直接为一个工具按钮设定一个 Action,而需要在窗口类的构造函数里编写代码,为界面上的各个工具按钮设置关联 的 Action。
2.QToolBox 组件
QToolBox 是工具箱组件类,工具箱是一种垂直分页的多页容器组件。在 UI 可视化设计时, 在工具箱组件上点击鼠标右键调出快捷菜单,可以分别使用 Insert Page 和 Delete Page 菜单项添加和删除页面。点击某个页面的标题栏,该页面就变为工具箱的当前页面。当界面上组件 toolBox 的第二个页面是当前页面时,属性编辑器里显示的内容如左图所示,toolBox 的第二个页面的界面设计结果如右图所示。
工具箱的每个页面就是一个 QWidget 组件,在页面的工作区可以放置任何其他界面组件。工具箱的第一个页面里放置了几个工具按钮,并设置为网格布局。第二个页面放置了一个复选框和两个工具按钮,也设置为网格布局,这里的两个工具按钮不需要与 Action 关联。第三个页面也放置了一些组件。
QToolBox 有一个信号 currentChanged(),在切换当前页面时组件发射此信号,其函数原型定义如下,其中的参数 index 是当前页面序号。
void QToolBox::currentChanged(int index)
QToolBox 类提供了用于页面控制、属性访问的各种接口函数。
3.设计 Action
本示例设计完成的 Action 列表如下图所示:
actSelPopMenu 用于“项选择”工具按钮,也就是窗口上具有下拉菜单的两个按钮。将 actSelPopMenu 的功能设置为与 actSelInvs 的完全相同。如图 所示,在信号与槽编辑器里,将 actSelPopMenu 的 triggered() 信号与 actSelInvs 的公有槽 trigger()连接。
4.QListWidget 组件
在窗口右侧的分组框里放置一个 QListWidget 组件,再放置其他几个按钮和编辑框。QListWidget 是列表组件, 每一行是一个QListWidgetItem 类型的对象,称为项或列表项。
双击界面上的 QListWidget 组件,可以打开下图所示的编辑器。在这个编辑器里可以添加、删除、上移、 下移列表项,也可以设置每个列表项的属性,包括文字、字体、文字对齐方式、背景色、前景色等。QListWidgetItem 有一个标志变量 flags,用于设置列表项的特性,flags 是枚举类型 Qt::ItemFlag 的枚举值的组合。
flags 可以设置如下一些特性:
• Selectable:列表项可被选择,对应枚举值 Qt::ItemIsSelectable。
• Editable:列表项可被编辑,对应枚举值 Qt::ItemIsEditable。
• DragEnabled:列表项可以被拖动,对应枚举值 Qt::ItemIsDragEnabled
。 • DropEnabled:列表项可以接收拖放的项,对应枚举值 Qt::ItemIsDropEnabled。
• UserCheckable:列表项可以被复选,若为 true,列表项前面会出现一个复选框,对应枚举值 Qt::ItemIsUserCheckable。 • Enabled:列表项可用,对应枚举值 Qt:: ItemIsEnabled。
• Tristate:自动改变列表项的复选状态,对应枚举值 Qt::ItemIsAutoTristate。该特性对 QTreeWidget 的节点有效,对 QListWidget 的列表项无效。
QListWidget 组件的列表项一般是在程序里动态创建的,后面会演示如何通过程序进行添加、 插入、删除列表项等操作。
二. QToolButton 与界面补充创建
1.QToolButton 的属性
一个工具按钮关联一个 Action 后,按钮的文字、图标、toolTip 等属性都将自动从关联的 Action 复制而来。但是在 UI 可视化设计时,我们无法为工具按钮设置关联的 Action。
在 UI 可视化设计时,对象名称为 tBtnSelectItem 的工具按钮的属性如图所示。
QToolButton 有几个新定义的属性。
(1)popupMode 属性。属性值是枚举类型 QToolButton::ToolButtonPopupMode。当按钮有下拉 菜单时,这个属性决定了弹出菜单的模式。几个枚举值的含义如下。
• QToolButton::DelayedPopup:按钮上没有任何附加的显示内容。如果按钮有下拉菜单,按下按钮并延时一会儿后,才显示下拉菜单。
• QToolButton::MenuButtonPopup:会在按钮右侧显示一个带箭头图标的下拉按钮。点击下拉按钮才显示下拉菜单, 点击工具按钮会执行按钮关联的 Action,而不会显示下拉菜单。列表组件上方的“项选择”按钮就设置为这种模式。
• QToolButton::InstantPopup:会在按钮的右下角显示一个 很小的下拉箭头图标,点击按钮就会立刻显示下拉菜单,即使工具按钮关联了一个 Action, 也不会执行这个 Action。工具栏上的“项选择”按钮就设置为这种模式。
(2)toolButtonStyle 属性。属性值是枚举类型 Qt::ToolButtonStyle,表示工具按钮上文字与图 标的显示方式, 与 QToolBar 类的同名属性的含义是一样的。界面上几个工具按钮的toolButtonStyle 属性都被设置为 Qt::ToolButtonTextBesideIcon。
(3)autoRaise 属性。如果设置为 true,按钮就没有边框,鼠标移动到按钮上时才显示按钮边 框。工具箱中的几个工具按钮的 autoRaise 属性都被设置为 true。
(4)arrowType 属性。属性值是枚举类型 Qt::ArrowType。默认值是 Qt::NoArrow,不会在按钮 上显示内容。另外还有 4 个枚举值,可以在按钮上显示表示方向的箭头图标。工具箱第二个页面 上的两个按钮就设置了这个属性。
2.QToolButton 的其他接口函数
除了与属性读写相关的一些接口函数,QToolButton 类还有两个主要的函数。
(1)setDefaultAction()函数。这个函数用于为工具按钮设置关联的 Action。设置关联的 Action 后,工具按钮的文字、图标、toolTip 等属性都与 Action 的一样,工具按钮的 triggered()信号自动 关联 Action 的 triggered()信号。这个函数的原型定义如下:
void QToolButton::setDefaultAction(QAction *action)
在 UI 可视化设计期间,无法为工具按钮设置 Action,而只能通过代码设置。所以,我们需要在窗口类的构造函数里编写代码为界面上的工具按钮设置关联的 Action。
(2)setMenu()函数。这个函数用于为工具按钮设置下拉菜单,其函数原型定义如下:
void QToolButton::setMenu(QMenu *menu)
QMenu 是菜单类,它直接从 QWidget 继承而来。在 Qt Designer 里,我们可以通过 Action 设计 窗口的菜单栏,但是不能可视化设计下拉菜单或某个组件的快捷菜单。要为工具按钮设计下拉菜单,需要通过代码动态创建 QMenu 对象,然后通过函数 setMenu()将其设置为工具按钮的下拉菜单。
3.代码补充创建界面
为了在可视化设计完成的界面基础上实现界面效果,我们在窗口类 MainWindow 中定义了两个私有函数,其中函数 setActionsForButton()用于为工具按钮设置关联的 Action,函数 createSelectionMenu()用于创建下拉菜单,并将其设置为工具按钮的下拉菜单。在 MainWindow 类的构造函数里调用这两个函数,就可以创建界面。
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow)
{
ui->setupUi(this);
setCentralWidget(ui->splitter); //设置中心组件
ui->listWidget->setContextMenuPolicy(Qt::CustomContextMenu); //定制快捷菜单
setActionsForButton();
createSelectionMenu();
}
void MainWindow::setActionsForButton()
{//为各个 QToolButton 类按钮设置 Action
ui->tBtnListIni->setDefaultAction(ui->actListIni); //初始化列表
ui->tBtnListClear->setDefaultAction(ui->actListClear); //清除列表
ui->tBtnListInsert->setDefaultAction(ui->actListInsert); //插入项
ui->tBtnListAppend->setDefaultAction(ui->actListAppend); //添加项
ui->tBtnListDelete->setDefaultAction(ui->actListDelete); //删除当前项
ui->tBtnSelALL->setDefaultAction(ui->actSelALL); //全选
ui->tBtnSelNone->setDefaultAction(ui->actSelNone); //空选
ui->tBtnSelInvs->setDefaultAction(ui->actSelInvs); //反选
}
void MainWindow::createSelectionMenu()
{
//创建下拉菜单
QMenu* menuSelection= new QMenu(this); //创建下拉菜单
menuSelection->addAction(ui->actSelALL); //全选
menuSelection->addAction(ui->actSelNone); //空选
menuSelection->addAction(ui->actSelInvs); //反选
//listWidget 上方的“项选择”按钮
ui->tBtnSelectItem->setPopupMode(QToolButton::MenuButtonPopup); //菜单弹出模式
ui->tBtnSelectItem->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
ui->tBtnSelectItem->setDefaultAction(ui->actSelPopMenu); //关联 Action
ui->tBtnSelectItem->setMenu(menuSelection); //设置下拉菜单
//工具栏上的“项选择”按钮,具有下拉菜单
QToolButton *aBtn= new QToolButton(this);
aBtn->setPopupMode(QToolButton::InstantPopup); //立刻显示下拉菜单
aBtn->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
aBtn->setDefaultAction(ui->actSelPopMenu); //关联 Action
aBtn->setMenu(menuSelection); //设置下拉菜单
ui->mainToolBar->addWidget(aBtn); //在工具栏上添加按钮
//在工具栏上添加分隔条和“退出”按钮
ui->mainToolBar->addSeparator();
ui->mainToolBar->addAction(ui->actQuit);
}
QMenu 是管理菜单的类,它的父类是 QWidget,菜单实际上是一种窗口。创建菜单主要会用到以下几个函数:
void QWidget::addAction(QAction *action) //添加 Action,创建菜单项
QAction *QMenu::addMenu(QMenu *menu) //添加菜单,创建子菜单
QAction *QMenu::addSeparator() //添加一个分隔条
QWidget::addAction()是 QMenu 的父类 QWidget 中定义的函数,它会添加 Action,并自动创建菜单项。QMenu 中还定义了多种参数形式的 addAction()函数,通过已设计好的 Action 创建菜单项是较简单的。
显示菜单可以使用函数 exec(),其函数原型定义如下:
QAction *QMenu::exec(const QPoint &p, QAction *action = nullptr)
参数 p 表示菜单的左上角坐标。在点击鼠标右键显示快捷菜单时,一般使用鼠标光标的当前位置 QCursor::pos()作为参数 p 的值。点击工具按钮显示下拉菜单的功能是由工具按钮内部的代码完成的,无须另外编写代码。
在函数 createSelectionMenu()里,我们将菜单 menuSelection 设置为两个工具按钮的下拉菜单, 但是这两个工具按钮弹出下拉菜单的模式不一样。
三. QListWidget 的操作
1.QListWidgetItem 类的主要接口函数
QListWidget 组件的列表项是 QListWidgetItem 对象。QListWidgetItem 类没有父类,所以没有属性,但是它有一些读取函数和设置函数,主要的接口函数如表所示。
读取函数 | 设置函数 | 数据类型 | 设置函数的功能 |
text() | setText() | QString | 设置项的文字 |
icon() | setIcon() | QIcon | 设置项的图标 |
data() | setData() | QVariant | 为项的不同角色设置数据,可设置用户数据 |
flags() | setFlags() | Qt::ItemFlags | 设置项的特性,是枚举类型 Qt::ItemFlag 的枚举值的组合 |
checkState() | setCheckState() | Qt::CheckState | 设置项的复选状态 |
isSelected() | setSelected() | bool | 设置为当前项,相当于点击了这个项 |
2.QListWidget 的主要接口函数
在 QListWidget 组件上点击一个项,这个项就是当前项,其所在的行就是当前行。QListWidget 类的主要接口函数如表所示,表中只列出了函数的返回值类型,省略了函数的输入参数。某些函数有多种参数形式。
分组 | 函数名 | 功能 |
添加或删除项 | void addItem() | 添加一个项 |
void addItems() | 根据一个字符串列表的内容,一次添加多个项 | |
void insertItem() | 在某一行前面插入一个项 | |
void insertItems() | 根据一个字符串列表的内容,一次插入多个项 | |
QListWidgetItem *takeItem() | 从列表组件中移除一个项,并返回这个项的对象指针,但是并不从内存中删除这个项 | |
void clear() | 移除列表中的所有项,并且从内存中删除对象 | |
项的访问 | QListWidgetItem *currentItem() | 返回当前项,返回 nullptr 表示没有当前项 |
void setCurrentItem() | 设置当前项 | |
QListWidgetItem *item() | 根据行号返回一个项 | |
QListWidgetItem *itemAt() | 根据屏幕坐标返回项,例如鼠标在列表组件上移动时,可以用这个函数返回光标所在的项 | |
int currentRow() | 返回当前行的行号,返回-1 表示没有当前行 | |
void setCurrentRow() | 设置当前行 | |
int row() | 返回一个项所在行的行号 | |
int count() | 返回列表组件中项的个数 | |
排序 | void setSortingEnabled() | 设置列表是否可排序 |
bool isSortingEnabled() | 列表是否可排序 | |
void sortItems() | 对列表进行排序,可指定排序方式为升序或降序 |
3.添加或删除项
几个与添加或删除项有关的 Action 的槽函数代码如下:
void MainWindow::on_actListIni_triggered()
{//“初始化列表”Action
QListWidgetItem *aItem;
QIcon aIcon;
aIcon.addFile(":/images/icons/check2.ico"); //设置图标
bool chk= ui->chkBoxListEditable->isChecked(); //是否可编辑
ui->listWidget->clear(); //清除列表
for (int i=0; i<10; i++)
{
QString str= QString("Item %1").arg(i);
aItem= new QListWidgetItem();
aItem->setText(str); //设置文字
aItem->setIcon(aIcon); //设置图标
aItem->setCheckState(Qt::Checked); //设置为 checked
if (chk) //可编辑,设置 flags
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable
|Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
else //不可编辑,设置 flags
aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled);
ui->listWidget->addItem(aItem); //添加一个项
}
}
void MainWindow::on_actListClear_triggered()
{//“清除列表”Action
ui->listWidget->clear();
}
void MainWindow::on_actListInsert_triggered()
{//“插入项”Action
QIcon aIcon(":/images/icons/check2.ico"); //定义图标变量并直接赋值
bool chk= ui->chkBoxListEditable->isChecked(); //是否可编辑
QListWidgetItem* aItem= new QListWidgetItem("Inserted Item");
aItem->setIcon(aIcon); //设置图标
aItem->setCheckState(Qt::Checked); //设置为 checked
if (chk) //可编辑,设置 flags
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable
|Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
else
aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled);
ui->listWidget->insertItem(ui->listWidget->currentRow(),aItem); //插入一个项
}
void MainWindow::on_actListAppend_triggered()
{//“添加项”Action
QIcon aIcon(":/images/icons/check2.ico"); //定义图标
bool chk= ui->chkBoxListEditable->isChecked(); //是否可编辑
QListWidgetItem* aItem= new QListWidgetItem("Added Item");
aItem->setIcon(aIcon); //设置图标
aItem->setCheckState(Qt::Checked); //设置为 checked
if (chk) //可编辑,设置 flags
aItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEditable
|Qt::ItemIsUserCheckable |Qt::ItemIsEnabled);
else
aItem->setFlags(Qt::ItemIsSelectable |Qt::ItemIsUserCheckable
|Qt::ItemIsEnabled);
ui->listWidget->addItem(aItem); //添加一个项
}
void MainWindow::on_actListDelete_triggered()
{//“删除当前项”Action
int row= ui->listWidget->currentRow(); //当前行的行号
QListWidgetItem* aItem= ui->listWidget->takeItem(row); //移除指定行的项
delete aItem; //需要手动删除对象
}
QListWidget 组件中的每一行是一个 QListWidgetItem 对象,要在列表中添加或插入一个项,一般是先创建一个 QListWidgetItem 对象,设置其文字、图标等特性,然后用函数 addItem()或 insertItem()将该对象加入列表。
QListWidgetItem 的函数 setFlags()用于设置项的一些特性,如是否可选、是否可编辑、是否有复选框等,其函数原型定义如下:
void QListWidgetItem::setFlags(Qt::ItemFlags flags)
参数 flags 是 Qt::ItemFlags 类型的标志变量,也就是枚举类型 Qt::ItemFlag 的各种枚举值的组 合。
注意,QListWidget 的 takeItem()函数的功能只是从列表中移除一个项,并不会删除这个QListWidgetItem 对象,如果要彻底删除这个项,需要使用 delete 显式地删除它。
4.遍历列表
可以通过 QListWidget 的接口函数遍历整个列表,并操作每个项。示例中创建的每个项都被设置为可复选的, 也就是每个项前面都会出现一个复选框。我们设计了 3 个 Action 来实现列表项的全选、空选、反选等选择功能,其中,实现反选功能的 Action 的槽函数代码如下:
void MainWindow::on_actSelInvs_triggered()
{//“反选”Action
QListWidgetItem *aItem;
int cnt= ui->listWidget->count(); //项的个数
for (int i=0; i<cnt; i++)
{
aItem= ui->listWidget->item(i); //获取一个项
if (aItem->checkState()!=Qt::Checked)
aItem->setCheckState(Qt::Checked);
else
aItem->setCheckState(Qt::Unchecked);
}
}
5.列表的排序
QListWidget 有一个属性 sortingEnabled,表示列表是否可排序,默认值为 false。注意,即使这个属性值为 false,也可以使用函数 sortItems()进行列表排序。如果 sortingEnabled 属性值为 true,通过运行 addItem()和 insertItem()新增的项将添加到列表的最前面。所以,如果要确保添加和插入 项的操作正常,属性 sortingEnabled 应该设置为 false。
可以使用函数 sortItems()对列表进行排序,其函数原型定义如下:
void QListWidget::sortItems(Qt::SortOrder order = Qt::AscendingOrder)
参数 order 表示排序方式,是枚举类型 Qt::SortOrder,有两种取值,其中 Qt::AscendingOrder 表示升序,Qt::DescendingOrder 表示降序。
,窗口上工具箱第二个页面上的一些组件可实现列表排序操作,其中的复选框和两个工具按钮的槽函数代码如下。这两个工具按钮没有关联 Action,直接为其 clicked()信号编写槽函数。
void MainWindow::on_tBtnSortAsc_clicked()
{
ui->listWidget->sortItems(Qt::AscendingOrder); //升序排序
}
void MainWindow::on_tBtnSortDes_clicked()
{
ui->listWidget->sortItems(Qt::DescendingOrder); //降序排序
}
void MainWindow::on_chkBoxSorting_clicked(bool checked)
{
ui->listWidget->setSortingEnabled(checked); //是否允许排序
}
6.QListWidget 的信号
QListWidget 定义的信号比较多,各信号的定义如下:
void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
void currentRowChanged(int currentRow) //当前项发生了切换
void currentTextChanged(const QString ¤tText) //当前项发生了切换
void itemSelectionChanged() //表示选择的项发生了变化
void itemChanged(QListWidgetItem *item) //项的属性发生了变化,如文字、复选状态等
void itemActivated(QListWidgetItem *item) //光标停留在某个项上,按 Enter 键时发射此信号
void itemEntered(QListWidgetItem *item) //鼠标跟踪时
void itemPressed(QListWidgetItem *item) //鼠标左键或右键按下
void itemClicked(QListWidgetItem *item) //点击
void itemDoubleClicked(QListWidgetItem *item) //双击
在 QListWidget 组件上点击某个项而导致当前项发生切换时,组件会发射 4 个信号,表示当前项发生了变化,这 4 个信号是 currentItemChanged()、currentRowChanged()、currentTextChanged() 和 itemSelectionChanged(),它们传递的参数不一样,应根据程序的需要选择合适的信号编写槽函数。
itemChanged()信号在项的属性发生变化时被发射,这些变化如修改了项的文字、图标或复选状态等。
点击一个项时,不管是否发生了当前项的切换,都会发射 itemPressed()和 itemClicked()信号。在一个项上点击鼠标右键时只会发射 itemPressed()信号,而不会发射 itemClicked()信号。
如果 QListWidget 的 mouseTracking 属性被设置为 true,当鼠标移动到某个项上时,组件就会发射 itemEntered()信号。mouseTracking 属性的默认值为 false。
在本示例中,我们为列表组件 listWidget 的 currentItemChanged()信号编写了槽函数,显示前一个项和当前项的标题。还为其他所有信号编写了槽函数,在一个文本框里显示信息,表示信号被发射了。我们可以通过程序进行各种测试,搞清楚各个信号的触发条件。其中几个信号的槽函数代码如下:
void MainWindow::on_listWidget_currentItemChanged(QListWidgetItem *current,
QListWidgetItem *previous)
{ //listWidget 的 currentItemChanged()信号的槽函数
QString str;
if (current != nullptr) //需要检测指针是否为空
{
if (previous == nullptr) //需要检测指针是否为空
str= "当前:"+current->text();
else
str= "前一项:"+previous->text()+"; 当前项:"+current->text();
ui->editCutItemText->setText(str);
}
ui->plainTextEdit->appendPlainText("currentItemChanged()信号被发射");
}
void MainWindow::on_listWidget_currentRowChanged(int currentRow)
{//currentRowChanged()信号
ui->plainTextEdit->appendPlainText(
QString("currentRowChanged()信号被发射,currentRow=%1").arg(currentRow));
}
void MainWindow::on_listWidget_currentTextChanged(const QString ¤tText)
{//currentTextChanged()信号
ui->plainTextEdit->appendPlainText(
"currentTextChanged()信号被发射,currentText="+currentText);
}
void MainWindow::on_listWidget_itemChanged(QListWidgetItem *item)
{// itemChanged()信号
ui->plainTextEdit->appendPlainText("itemChanged()信号被发射,"+item->text());
}
void MainWindow::on_listWidget_itemSelectionChanged()
{// itemSelectionChanged()信号
ui->plainTextEdit->appendPlainText("itemSelectionChanged()信号被发射");
}
程序运行时,对 listWidget 进行各种操作,例如点击并切换当前项,点击但不切换当前项,点击列表项前面的复选框,修改项的文字等。根据左侧文本框中显示的信息就可以知道列表组件发射了哪些信号。下图展示的是点击并切换当前项时发射信号的信息。
四. 创建右键快捷菜单
每个继承自 QWidget 的类都有 customContextMenuRequested()信号, 在一个组件上点击鼠标右键时,组件发射这个信号,用于请求创建快捷菜单。如果为此信号编写槽函数,就可以创建和运行快捷菜单。
要使 QWidget 组件在点击鼠标右键时发射 customContextMenuRequested()信号,还需要设置其 contextMenuPolicy 属性,设置该属性的函数原型定义如下:
void QWidget::setContextMenuPolicy(Qt::ContextMenuPolicy policy)
参数 policy 是枚举类型 Qt::ContextMenuPolicy,有如下几种枚举值。
• Qt::NoContextMenu:组件没有快捷菜单,由其父容器组件处理快捷菜单。
• Qt::PreventContextMenu:阻止快捷菜单,并且点击鼠标右键事件也不会交给父容器组件处理。 • Qt::DefaultContextMenu:默认的快捷菜单,组件的 QWidget::contextMenuEvent()事件被自动处理。某些组件有自己的默认快捷菜单,例如 QPlainTextEdit 的 contextMenuPolicy 属性默认设置为这个值,在无须任何编程的情况下,运行时点击鼠标右键就会出现一个标准的编辑操作快捷菜单,只是菜单文字是英文的。
• Qt::ActionsContextMenu:自动根据 QWidget::actions()返回的 Action列表创建并显示快捷菜单。
• Qt::CustomContextMenu:组件发射 customContextMenuRequested()信号,由用户编程实现创建并显示快捷菜单。
本示例中创建了操作 listWidget 的一些 Action,可以用这些 Action 为 listWidget 创建快捷菜单。 在 Qt Designer 里将 listWidget 的 contextMenuPolicy 属性设置为 Qt::CustomContextMenu,然后为其 customContextMenuRequested()信号编写槽函数,代码如下:
void MainWindow::on_listWidget_customContextMenuRequested(const QPoint &pos)
{
Q_UNUSED(pos);
QMenu* menuList= new QMenu(this); //创建菜单
//添加 Action 将其作为菜单项
menuList->addAction(ui->actListIni);
menuList->addAction(ui->actListClear);
menuList->addAction(ui->actListInsert);
menuList->addAction(ui->actListAppend);
menuList->addAction(ui->actListDelete);
menuList->addSeparator();
menuList->addAction(ui->actSelALL);
menuList->addAction(ui->actSelNone);
menuList->addAction(ui->actSelInvs);
menuList->exec(QCursor::pos()); //在鼠标光标位置显示快捷菜单
delete menuList; //菜单显示完后,需要删除对象
}
程序运行时首先创建一个 QMenu 类型的对象 menuList,然后利用 QMenu::addAction()函数添加已经设计好的 Action 作为菜单项。创建完菜单后,使用 QMenu::exec()函数显示快捷菜单:
menuList->exec(QCursor::pos());
这样会在鼠标光标当前位置显示快捷菜单,静态函数 QCursor::pos()获取鼠标光标当前位置。快捷菜单的运行效果如图所示: