QAction系列詳解


  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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM