QAction系列详解

一、QAction类详解

【详细描述】

QAction类提供了抽象的用户界面action,这些action可以被放置在窗口部件中。
        应用程序可以通过菜单,工具栏按钮以及键盘快捷键来调用通用的命令。由于用户期望每个命令都能以相同的方式执行,而不管命令所使用的用户界面,
这个时候使用action来表示这些命令就显得十分有用。
         Actions可以被添加到菜单和工具栏中,并且可以自动保持在菜单和工具栏中的同步。例如,在一个字处理软件中,如果用户在工具栏中按下了Bold按钮,那么菜单中的Bold选项就会自动被选中。
         Actions可以作为独立的对象被创建,但是我们也可以在构建菜单的时候创建它们;QMenu类包含了非常简便的方法用于创建适合用作菜单项的actions。
       QAction可以包括一个图标,菜单文本,快捷键,状态文本,"What`s This"文本以及一个tooltip。这些内容的绝大部分都可以在构造函数中设置。也可以通过setIcon(),setIconText(),setShortCut(),setStatusTip(),setWhatsThis和SetToolTip()函数分别设置。对于菜单项,我们还可以通过
setFont()单独为它们设置font。
       可以通过QWidget::addAction()或者是QGraphicsWidget::addAction()函数将Actions添加到窗口部件上。注意,只有将Actions添加到窗口部件上之后,我们才可以使用这些actions;当actions的快捷键是全局的时候,我们也必须先将actions添加到窗口部件上。
       一旦QAction被创建了,那么就必须将它添加到相关的菜单和工具栏上,然后将它们链接到实现相应action功能的槽函数上。例如:
openAct = new QAction(QIcon(":/images/open.png"), tr("&Open..."), this);
openAct->setShortcuts(QKeySequence::Open);
openAct->setStatusTip(tr("Open an existing file"));
connect(openAct, SIGNAL(triggered()), this, SLOT(open()));

fileMenu->addAction(openAct);
fileToolBar->addAction(openAct);
        我们建议将actions作为使用它们的窗口的孩子创建。在绝大多数情况下,actions都是应用程序主窗口的孩子。

类的枚举成员变量:

这个枚举类型主要是在调用QAction::activate()函数的时候被使用到。我们来看看QAction::activate()函数的原型:

从上面可以看出,我们使用该函数发射信号,而参数event则指明了发射的信号类型。基于action的widgets可以自己发射信号,然而我们也可以显式的调用本API来发射信号。

由于Mac OS X系统的一些特性,Qt 会对一些菜单项进行自动排列。比如,如果你的菜单是“关于”、“设置”、“首选项”、“退出”等等,我们可以给它们分配一个角色,Qt 则会根据这些角色对菜单项的顺序作出正确的排列。方法是,设置 QAction::menuRole 属性,例如:AboutRole、PreferencesRole、QuitRole 或者 NoRole。举例

来说,我们可以将“设置”菜单项作为 Mac OS X 的 Application::preferences。

QAction::MenuRole类型的枚举主要描述了在Mac OS X系统上,action如何移动到应用程序的菜单上。设置这个值只对菜单上的直接菜单有效,对子菜单无效。例如:如果有一个File菜单,该File菜单又包含有子菜单,那么如果你针对子菜单设置这些值,那么这些值永远不会起作用。

该优先级用于表明action在用户界面上的优先级。例如,当你的工具栏设置了Qt::ToolButtonTextBesideIcon模式,那么低优先级的actions将不会显示出标签。

【示例】

(1) 使用Action构造工具栏和菜单栏

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    initMenu();
    initToolBar();
}

void MainWindow::initMenu()
{
    /* 初始化File菜单 */
    fileMenu = new QMenu(tr("File"), this);
    fileOpenAction = new QAction("&Open...", this);
    fileSaveAction = new QAction("&Save...", this);
    fileMenu->addAction(fileOpenAction);
    fileMenu->addAction(fileSaveAction);

    /* 初始化Edit菜单 */
    editMenu = new QMenu("&Edit");
    editCopyAction = editMenu->addAction("&Copy");
    editCutAction = editMenu->addAction("&Cut");

    /* 将菜单添加到菜单栏上 */
    QMenuBar *menuBar = this->menuBar();
    menuBar->addMenu(fileMenu);
    menuBar->addMenu(editMenu);
}

void MainWindow::initToolBar()
{
    /* 初始化FileToolBar */
    fileToolBar = new QToolBar(this);
    fileToolBar->addAction(fileOpenAction);
    fileToolBar->addAction(fileSaveAction);

    /* 初始化EditToolBar */
    editToolBar = new QToolBar(this);
    editToolBar->addAction(editCopyAction);
    editToolBar->addAction(editCutAction);

    /* 将工具添加到工具栏上 */
    addToolBar(Qt::TopToolBarArea, fileToolBar);
    addToolBar(Qt::TopToolBarArea, editToolBar);
}

MainWindow::~MainWindow()
{
    
}

(2)测试QAction::activate(QAction::ActionEvent)

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    initMenu();
    initToolBar();
    initConnect();
}
void MainWindow::initConnect()
{
    connect(fileOpenAction, SIGNAL(triggered()),
            this, SLOT(sendActivate()));
    connect(fileSaveAction, SIGNAL(hovered()),
            this, SLOT(ansHovered()));
}

void MainWindow::sendActivate()
{
    /* 这将会导致fileSaveAction发送信号QAction::hovered() */
    fileSaveAction->activate(QAction::Hover);
}

void MainWindow::ansHovered()
{
    qDebug("Ans!!!");
}

运行结果:

(3)测试QAction::Priority

void MainWindow::initMenu()
{
    /* 初始化File菜单 */
    fileMenu = new QMenu(tr("File"), this);
    fileOpenAction = new QAction("&Open...", this);
    fileSaveAction = new QAction("&Save...", this);
    fileMenu->addAction(fileOpenAction);
    fileMenu->addAction(fileSaveAction);

    /* 初始化Edit菜单 */
    editMenu = new QMenu("&Edit");
    editCopyAction = editMenu->addAction("&Copy");
    editCutAction = editMenu->addAction(QIcon(":/cut.PNG"), "&Cut");
    //editCutAction->setPriority(QAction::LowPriority);

    /* 将菜单添加到菜单栏上 */
    QMenuBar *menuBar = this->menuBar();
    menuBar->addMenu(fileMenu);
    menuBar->addMenu(editMenu);
}

void MainWindow::initToolBar()
{
    /* 初始化FileToolBar */
    fileToolBar = new QToolBar(this);
    fileToolBar->addAction(fileOpenAction);
    fileToolBar->addAction(fileSaveAction);

    /* 初始化EditToolBar */
    editToolBar = new QToolBar(this);
    editToolBar->addAction(editCopyAction);
    editToolBar->addAction(editCutAction);

    /* 将工具添加到工具栏上 */
    addToolBar(Qt::TopToolBarArea, fileToolBar);
    addToolBar(Qt::TopToolBarArea, editToolBar);

    /* 设置工具栏为QT::ToolButtonTextBesideIcon */
    this->setToolButtonStyle(Qt::ToolButtonTextBesideIcon);
}

此时注释掉了设置优先级的语句,图标和文字均能显示出来,效果如下图:

取消上面的注释;

/* 初始化Edit菜单 */
    editMenu = new QMenu("&Edit");
    editCopyAction = editMenu->addAction("&Copy");
    editCutAction = editMenu->addAction(QIcon(":/cut.PNG"), "&Cut");
    editCutAction->setPriority(QAction::LowPriority);

运行效果如下:

二、QActionGroup类详解

【详细描述】

QActionGroup类将actions分组。
       在某些情况下将QAction分组是十分有用的。例如,如果你有一个Left Align的action,一个Right Align的action,一个Justify的action,
以及一个Center action,在统一时刻所有这些actions只能有一个被激活。一种简便的做法就是将这些actions以分组的方式组织。
下面是一个示例:
alignmentGroup = new QActionGroup(this);
alignmentGroup->addAction(leftAlignAct);
alignmentGroup->addAction(rightAlignAct);
alignmentGroup->addAction(justifyAct);
alignmentGroup->addAction(centerAct);
leftAlignAct->setChecked(true);
        在上面的示例中,我们创建了一个action组。由于action group默认是互斥的,因此在同一时刻只有一个会被选中。
        当组内的某个action被选中的时候,QActionGroup就会发射triggered()信号。通常情况下,组内的每个action发射自己的triggered()信号。
        正如上面提到的,action group默认是互斥的;它确保在同一时刻只有一个action会被选中。如果你想创建一个action group而不想时它们是互斥关系,那么你可以通过调用setExclusive(false)来关闭互斥关系。
        可以使用addAction()函数将action添加到action group中,然而更常见的做法是在创建action的时候指定一个group;这确保了这些actions具有同一个父亲。可以通过在group中添加分割线使得各个action分开显示,可以使用QAction的setSeparator()添加分割线。通常使用QWidget::addActions()函数将action group添加到窗口部件上。

【示例】

    /* 初始化Action菜单 */
    actionMenu = new QMenu("Action");
    leftAction = new QAction("Left", this);
    rightAction = new QAction("Right", this);
    centerAction = new QAction("Center", this);
    justifyAction = new QAction("Justify", this);
    actionGroup = new QActionGroup(this);
    actionMenu->addAction(actionGroup->addAction(leftAction));
    actionMenu->addAction(actionGroup->addAction(rightAction));
    actionMenu->addAction(actionGroup->addAction(centerAction));
    actionMenu->addAction(actionGroup->addAction(justifyAction));

可以使用下面的槽函数验证默认情况下,一次只有一个action可以被选中。当然也可以设置action的

bool isExclusive () const 

为false,使得一次可以选中多个:

void MainWindow::initConnect()
{
    connect(fileOpenAction, SIGNAL(triggered()),
            this, SLOT(sendActivate()));
    connect(fileSaveAction, SIGNAL(hovered()),
            this, SLOT(ansHovered()));

    connect(leftAction, SIGNAL(triggered()),
            this, SLOT(ansTriggered()));
    connect(rightAction, SIGNAL(triggered()),
            this, SLOT(ansTriggered()));
    connect(centerAction, SIGNAL(triggered()),
            this, SLOT(ansTriggered()));
    connect(justifyAction, SIGNAL(triggered()),
            this, SLOT(ansTriggered()));
}

运行效果:

备注:

一、放置到ActionGroup中就默认是exclusive。
二、是否出现选中的标志"小圆点"是通过设置setcheckable完成的。两者并无联系。

关于QActionGroup的使用,我发的一个帖子中有提到,再次感谢网友jdwx1

帖子的连接如下,感兴趣的可以看看QActionGroup只对子菜单生效?

三、QWidgetAction类详解

【详细描述】

QWidgetAction通过接口方式继承自QAction,用于将自定义的widget插入基于action的容器,例如工具栏。
        出现在应用程序中的绝大多数的actions都是代表了一个菜单项或工具栏中的一个按钮。然而有时候我们也许要复杂一点的widgets。例如,字处理程序工具栏中使用QComboBox实现zoom action,实现不同程度的缩放。QToolBar提供了QToolBar::insertWidget()函数可以十分方便的将单个widget插入到合适的位置。然而,如果你想在多个容器中实现自定义widget的action,那么你就必须实现QWidgetAction的子类。
        如果QWidgetAction添加到QToolBar,那么就会调用QWidgetAction::createWidget()。我们可以重新实现这个函数创建自定义的widget。
        如果将一个action从容器widget上删除,那么就会调用QWidgetAction::deleteWidget(),调用该函数的参数就是上面创建的自定义widget。该函数的默认实现是将widget隐藏,然后使用QObject::deleteLater()删除它。
        如果你只有一个自定义的widget,那么你就可以使用setDefaultWidget()函数将它设置为默认的widget。那么以后当action被添加到QToolBar上时,就会自动将该自定义的widget添加到QToolBar上。如果将仅有一个默认widget的QWidgetAction同时添加到两个工具栏上,那么仅有第一个添加才会显示出来。QWidgetAction接管了默认的widget。
        注意:这取决于widget激活action,例如重新实现鼠标事件处理者,然后调用QAction::trigger()。
Mac OS X:在Mac OS X上,如果你将一个widget添加到应用程序菜单栏的某个菜单上,那么该widget可以显示出来,并且可以实现功能,只是有一些限制:
1、该widget的父对象不再是QMenu而是原生的菜单视图。如果你在其他地方显示菜单(例如作为一个弹出菜单),那么该菜单不会显 示在你期望的地方;
2、针对该widget的Focus/Keyboard处理不再可用;
3、由于Apple的设计,该widget的鼠标轨迹暂时不可用;
4、将triggered()信号链接到打开模态对话框的槽函数上会导致应用程序崩溃(在Mac OS X10.4,这被告知是Apple的一个BUG),一个规避的方法是使用QueuedConnection代替DirecConnection。

【示例】

本示例代码来自:http://www.qtcn.org/bbs/simple/?t28610.html

功能:设置QMenu中菜单项的高度

代码片段:

class MyMenuItem:public QWidget
{
    Q_OBJECT
    public:
    MyMenuItem(QWidget *parent)
    {
        new QLabel("test",this);
    }
};
int main(int argc, char *argv[])
{
    popupMenu = new QMenu(this); 
    QAction *action1 = new QAction(tr("&New1"), this);
    QAction *action2 = new QAction(tr("&New2"), this);
    QAction *action3 = new QAction(tr("&New3"), this);
    QAction *action4 = new QAction(QIcon("./load.png"), tr("Bookstore"), this);
    popupMenu->addAction(action1);
    popupMenu->addAction(action2);
    popupMenu->addAction(action3);
    popupMenu->addAction(action4);
	
	MyMenuItem *item1 = new MyMenuItem(this);
    item1->setFixedSize(100,100);    //这里可以设置大小
    QWidgetAction *action1 = new QWidgetAction(popupMenu);
    action1->setDefaultWidget(item1);
	
    MyMenuItem *item2 = new MyMenuItem(this);
    QWidgetAction *action2 = new QWidgetAction(popupMenu);
    action2->setDefaultWidget(item2);
	
    MyMenuItem *item3 = new MyMenuItem(this);
    QWidgetAction *action3 = new QWidgetAction(popupMenu);
    action3->setDefaultWidget(item3);	
    popupMenu->exec();
}

http://blog.csdn.net/chenlong12580/article/details/8872035

QAction系列详解的更多相关文章

  1. QAction类详解:

    先贴一段描述:Qt文档原文: Detailed Description The QAction class provides an abstract user interface action tha ...

  2. MySQL系列详解八:MySQL多线程复制演示-技术流ken

    前言 Mysql 采用多线程进行复制是从 Mysql 5.6 开始支持的内容,但是 5.6 版本下有缺陷,虽然支持多线程,但是每个数据库只能一个线程,也就是说如果我们只有一个数据库,则主从复制时也只有 ...

  3. iOS开发技巧系列---详解KVC(我告诉你KVC的一切)

    KVC(Key-value coding)键值编码,单看这个名字可能不太好理解.其实翻译一下就很简单了,就是指iOS的开发中,可以允许开发者通过Key名直接访问对象的属性,或者给对象的属性赋值.而不需 ...

  4. MySQL系列详解六:MySQL主从复制/半同步演示-技术流ken

    前言 随着技术的发展,在实际的生产环境中,由单台MySQL数据库服务器不能满足实际的需求.此时数据库集群就很好的解决了这个问题了.采用MySQL分布式集群,能够搭建一个高并发.负载均衡的集群服务器.在 ...

  5. MySQL系列详解三:MySQL中各类日志详解-技术流ken

    前言 日志文件记录了MySQL数据库的各种类型的活动,MySQL数据库中常见的日志文件有 查询日志,慢查询日志,错误日志,二进制日志,中继日志 .下面分别对他们进行介绍. 查询日志 1.查看查询日志变 ...

  6. OpenStack计费项目Cloudkitty系列详解(一)

    云计算是一种按需付费的服务模式,虽然OpenStack前期在计量方面走了些“弯路”,但现在的ceilometer.gnocchi.aodh.panko项目的稳步并进算是让其峰回路转.然而,目前来看Op ...

  7. 阿里云系列——7.阿里云IIS系列详解(过程+通用+最新)

    网站部署之~阿里云系列汇总 http://www.cnblogs.com/dunitian/p/4958462.html 先讲IIS系列,Linux部署以后再继续讲 先打开主机管理平台,确认域名绑定 ...

  8. 【转】目标检测之YOLO系列详解

    本文逐步介绍YOLO v1~v3的设计历程. YOLOv1基本思想 YOLO将输入图像分成SxS个格子,若某个物体 Ground truth 的中心位置的坐标落入到某个格子,那么这个格子就负责检测出这 ...

  9. magento缓存系列详解:clean cache

    cache是一个很大的概念,涉及的内容方方面面,magento cache是基于zend的,如果你对zend cache理解很深的话,相信magento cache也不再话下,本篇文章着重介绍Flus ...

随机推荐

  1. 一道有关球赛队员分配的C++程序题目

    题目描述: 两个球队进行比赛,各出三人.甲队为a,b,c三人,乙队为x,y,z三人.已经抽签决定比赛名单. 有人向队员打听比赛安排的名单.a说他不和x比,c说他不和x,z比,请编程找出三队赛手的名单. ...

  2. 【转】android4.1.2 CTS测试总结

    原文网址:http://blog.csdn.net/bboyliaoye/article/details/17299259 公司客户的产品要过google GMS认证,首先要过的就是兼容性测试(CTS ...

  3. 杭电1142(最短路径+dfs)

    A Walk Through the Forest Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Jav ...

  4. HDU 1074 Doing Homework (状态压缩 DP)

    题目大意: 有 n 项作业需要完成,每项作业有上交的期限和需完成的天数,若某项作业晚交一天则扣一分.输入每项作业时包括三部分,作业名称,上交期限,完成所需要的天数.求出完成所有作业时所扣掉的分数最少, ...

  5. nodejs学习笔记之包、模块实现

        简单了解了node的安装和一些基本的常识之后,今天学习了node中很重要的包和模块的一些知识点.       首先学习一下包的规范,它由包结构和包描述两部分组成.包结构用于组织包的各种文件,包 ...

  6. Js操作Select

    jquery操作select(取值,设置选中) 每一次操作select的时候,总是要出来翻一下资料,不如自己总结一下,以后就翻这里了. 比如<select class="selecto ...

  7. PC-CSS-分隔线

    单个标签实现分隔线: 点此查看实例展示 .demo_line_01{ padding: 0 20px 0; margin: 20px 0; line-height: 1px; border-left: ...

  8. androidHandler讲解

    秒钟还没有完成的话,会收到Android系统的一个错误提示  "强制关闭".  这个时候我们需要把这些耗时的操作,放在一个子线程中,因为子线程涉及到UI更新,Android主线程是 ...

  9. XCode Could not launch &quot;&quot; failed to get the task for process

    在Xcode下编译project正常,在模拟器下执行正常,最后在真机上执行的时候出现了例如以下错误: Could not launch "FeedMeWorms" failed t ...

  10. maven报错cannot change version of project facet

    用Eclipse创建Maven结构的web项目的时候选择了默认的catalog,由于这个catalog比较老,用的servlet还是2.3,而现在最少也是2.5,所以经常会出现问题,在Projecdt ...