首页 > 代码库 > QAction类详解:

QAction类详解:

先贴一段描述:
Qt文档原文:

Detailed Description

The QAction class provides an abstract user interface action that can be inserted into widgets.

In applications many common commands can be invoked via menus, toolbar buttons, and keyboard shortcuts. Since the user expects each command to be performed in the same way, regardless of the user interface used, it is useful to represent each command as an action.

Actions can be added to menus and toolbars, and will automatically keep them in sync. For example, in a word processor, if the user presses a Bold toolbar button, the Bold menu item will automatically be checked.

Actions can be created as independent objects, but they may also be created during the construction of menus; the QMenu class contains convenience functions for creating actions suitable for use as menu items.

A QAction may contain an icon, menu text, a shortcut, status text, "What‘s This?" text, and a tooltip. Most of these can be set in the constructor. They can also be set independently with setIcon(), setText(), setIconText(), setShortcut(), setStatusTip(), setWhatsThis(), and setToolTip(). For menu items, it is possible to set an individual font with setFont().

Actions are added to widgets using QWidget::addAction() or QGraphicsWidget::addAction(). Note that an action must be added to a widget before it can be used; this is also true when the shortcut should be global (i.e., Qt::ApplicationShortcut as Qt::ShortcutContext).

Once a QAction has been created it should be added to the relevant menu and toolbar, then connected to the slot which will perform the action. For example:

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);
We recommend that actions are created as children of the window they are used in. In most cases actions will be children of the application‘s main window.

一、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()));

}

运行效果:

技术分享

备注:

1、放置到ActionGroup中就默认是exclusive。

2、是否出现选中的标志"小圆点"是通过设置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://qiusuoge.com/12287.html

QAction类详解: