技术标签: layout filter QT qt action menu signal
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 )函数。
实例:
void CGuiMainwindow::contextMenuEvent(QContextMenuEvent* e)
{
QMenu *menu = new QMenu();
menu->addSeparator();
menu->addSeparator();
menu->addAction(Act_Maxsize);
menu->addSeparator();
menu->addSeparator();
menu->addAction(Act_Normal);
menu->addSeparator();
menu->addSeparator();
menu->exec(e->globalPos());
delete menu;
}
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());
}
}
4)二级菜单实例
准备工作一:定义和实现需要的action,可以用代码编写,也可以用creator进行制作。代码编写如下
头文件定义:
QMenu *popupMenu; /*popupMenu*/ //主菜单
QMenu *twoPictures; /*two pictures*/ // 二级菜单
QMenu *onePictures; /*one pictures*/ // 二级菜单
QAction *firstChannel; /*channel 1*/
QAction *secondChannel; /*channel 2*/
QAction *thirdChannel; /*channel 3*/
QAction *forthChannel; /*channel 4*/
QAction *frontSection;
QAction *backSection;
QActionGroup *channels; //用来实现子菜单选项互斥
QActionGroup *sections;
void layout3::createActions(void)
{
firstChannel = new QAction(tr("first channel"), this); //创建新的菜单项
firstChannel->setCheckable(true); //属性是可选的
connect(firstChannel, SIGNAL(triggered()), this, SLOT(firstChannelSlot())); //该菜单项的连接信号和槽
secondChannel = new QAction(tr("second channel"), this);
secondChannel->setCheckable(true);
connect(secondChannel, SIGNAL(triggered()), this, SLOT(secondChannelSlot()));
thirdChannel = new QAction(tr("third channel"), this);
thirdChannel->setCheckable(true);
connect(thirdChannel, SIGNAL(triggered()), this, SLOT(thirdChannelSlot()));
forthChannel = new QAction(tr("forth channel"), this);
forthChannel->setCheckable(true);
connect(forthChannel, SIGNAL(triggered()), this, SLOT(forthChannelSlot()));
frontSection = new QAction(tr("front section"), this);
frontSection->setCheckable(true);
connect(frontSection, SIGNAL(triggered()), this, SLOT(frontSectionSlot()));
backSection = new QAction(tr("back section"), this);
backSection->setCheckable(true);
connect(backSection, SIGNAL(triggered()), this, SLOT(backSectionSlot()));
channels = new QActionGroup(this); //创建菜单项组,里面的菜单项为互斥
channels->addAction(firstChannel); //添加菜单项到组里
channels->addAction(secondChannel);
channels->addAction(thirdChannel);
channels->addAction(forthChannel);
firstChannel->setChecked(true); //设置默认的菜单组的菜单项状态,firstChannel被选中
sections = new QActionGroup(this); //同上
sections->addAction(frontSection);
sections->addAction(backSection);
frontSection->setChecked(true);
}
/*
* 槽函数准备为
*/
void layout3::firstChannelSlot(void)
{
}
void layout3::secondChannelSlot(void)
{
}
void layout3::thirdChannelSlot(void)
{
}
void layout3::forthChannelSlot(void){
}
void layout3::frontSectionSlot(void)
{}
void layout3::backSectionSlot(void)
{}
最后进行菜单的编辑,重写
void contextMenuEvent ( QContextMenuEvent *event);
void layout3::contextMenuEvent(QContextMenuEvent* e)
{
popupMenu = new QMenu(); //创建主菜单
onePictures = popupMenu->addMenu("one pictures"); //在主菜单中创建子菜单one pictures
onePictures->addAction(firstChannel); //把action项放入子菜单中
onePictures->addAction(secondChannel);
onePictures->addAction(thirdChannel);
onePictures->addAction(forthChannel);
popupMenu->addSeparator();
popupMenu->addSeparator();
twoPictures = popupMenu->addMenu("two pictures"); //在主菜单中创建子菜单two pictures
twoPictures->addAction(frontSection);
twoPictures->addAction(backSection);
popupMenu->addSeparator();
popupMenu->addSeparator();
popupMenu->addAction(ui->actionAbout); //把action项放入主菜单中
popupMenu->addSeparator();
popupMenu->addSeparator();
popupMenu->addAction(ui->actionBuild);
popupMenu->addSeparator();
popupMenu->addSeparator();
popupMenu->exec(e->globalPos()); //选择菜单弹出的位置
delete popupMenu;
popupMenu = NULL;
}
结果如下:
先说需求:需要后端和前端通信需要将数据加密后传输前端 <-> 加密数据 <-> 后端总的来说PHP的使用时最简单的,坑最少,当之无愧世界上最好的语言以下是代码实现以下代码实现统一使用参数AES加密算法32位秘钥key (通过给定秘钥取md5值获得) 12345616位初始向量iv 秘钥key的md5值前16位加密数据 "123456789"1、PHP...
如何卸载windows系统很多刚刚装完xp、windows 7系统的人,都有可能会问,如果我想换过系统是不是应该先删掉这个系统再重新装一个。或者我的 电脑要重装系统,有没有必要把原来的系统卸载掉呢?就带着疑问接着看下文吧!更多消息请关注应届毕业生网!1 如何卸载windos系统一般来说,我们电脑都是单系统。想要卸载系统,最快的方法就是格式化系统所在的盘,如单系统、我们的系统都是存放在C盘,你只需要...
在互联网时代,企业产品推广不能仅仅依靠下线,这样投入的太高成本高。更上互联网发展,做网络推广是必须的,下面襄阳seo就和大家讲讲2018年熟知的网络推广方法。 2018年网络推广的常用方法...
设备和环境:1、树莓派3b;2、ubuntu mate系统 linux内核是4.4.38;3、DHT11传感器;4、Qt 5.5.1。 功能需求:1、读取DHT11传感器的数据,并将温湿度显示在窗口中。 功能实现:1、建立Qt工程,然后编写代码,具体如下: //此为dht11.cpp文件#include "dth11.h"#include "u...
在使用高级定时器的时候遇到几个坑,在这里记录一下。主要是有些设置和普通定时器不太一样,如果照搬普通定时器的设置就会出错。1.初始化设置里多了一项TIM_TimeBaseInitStrue.TIM_RepetitionCounter = 0;//重复计数设置是高级定时器独有的,具体作用可以查阅参考手册2.高级定时器如果要用来输出PWM波则必须进行PWM输出使能TIM_CtrlPWMOutputs(TIM1, ENABLE);//TIM1 PWM输出使能3.定时器1的更新中断服务函数
事件详情请看 GitHub Issue 及 justjavac 发布的文章有人统计出目前引用了 event-stream 的 3900 多个包,如下(名次越靠前使用的人越多):ps-treenodemonflatmap-streampstree.remynpm-run-allgulp-injectgulp-livereloadbrowserstack-localgulp-nod...
网站制作的方式有很多种,制作步骤也不尽相同,但是对于不懂代码也想自己建网站的新手来说,用自助建站平台来制作自己的网站就是最佳的选择,这里分享的网站制作的基本步骤可以说是谁都能看懂,谁都能操作实现。具体介绍如下:百度搜索:自助建站系统1.在展示的网站模板中找一个喜欢的,点击“使用”进行下载,下载之前也可以先点击“查看”进行预览。这样,模板下载就算完成了;2.接着点击“网站设计”,对网站主题、页...
使用JAVA来写一些带有图形界面的程序是一件很有意思的事情。JAVA不光可以编写服务器端程序,用它来编写客户端程序也是非常棒的,本文就来详细讲解一个最简单的JAVA图形界面程序:一个窗体上有3个按钮可以改变窗体的背景颜色。 首先,任何一个图形界面程序都有一个最外层的框架。在JAVA中,这个框架就是JFrame类。需要注意的是,你不可以往JFrame上面添加按钮
import java.util.*;public class ThreeCompare {public static void main(String[] args) {int a, b, c;Scanner input = new Scanner(System.in);System.out.println("请输入三个整数:");a = input.nextInt();b = input.ne...
这是个大坑 平时装个JDK这么简单的事 在WSL上问题还真不少安装环境适用于 Linux 的 Windows 子系统:Ubuntu-18.04 (默认)以前都是用的centos,直接yum localinstall ./jdk-???-linux-x64.rpm就可以安装本地的RPM包了。但是现在使用的Ubuntu,只能安装DEB包,查询了一下有三种安装方式:RPM包转制为DEB包使用开箱即用的t...
我刚刚将我的网站从apache2移动到Nginx作为我的新Web服务器后端 . 得到了爱问题啊哈 .Web主机导演中的HTML文件在php文件生成主目录之前工作然后我从nginx收到502错误来自nginx的错误消息:SO认为它是代码:)>tail -f /var/log/nginx/error.log>2018/07/03 15:27:45 [alert] 1275#1275: *4...
安装JTest拷贝破解文件lic_client.jar到\Parasoft\Test\9.4\plugins\com.parasoft.xtest.libs_9.4.0.20120412\Parasoft\创建附带案例,例如JPetStore、WebGoat等JTest静态分析包含安全编程规则扫描参考:jtest9_users_guide.pdfLesson 21: Using Jtest to