2020年6月1日 星期一

MenuBar 的基本應用

MenuBar 的基本應用

前言

  這次來說明應用程式視窗常出現的選單如何在 Qt 裡編輯,這次會說明在 UI 編輯器裡編輯與用程式來編輯的作法,在此做個紀錄。

內容

  先到 [ GitLab ] HelloQt 下載範例,這次應用的專案路徑
(HelloQt' directory)/MenuBar/Basic,在 Qt Creator 開啟設計介面會看到以下
範例的設計介面

執行的結果如下
範例的執行結果

範例會在每次按下以 action 為開頭的選項後顯示偵錯訊息,也會在城市開始時顯示一些偵錯訊息。在設計的介面要新增選項,可以在下圖
在設計介面新增選項

雙擊該處就可以輸入選項的名稱,並且可以在物件視窗裡看到它在"menubar"裡被新增,型態可能是 QMenu 或 QAction ,就看它有沒有在 Child 裡新增來決定,如下圖
在物件視窗裡狀況

接著來看如何在程式操作,先看到 MainWindow::MainWindow() ,程式碼如下
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  //manual add
  //Don't use follow
  //QMenu* pMyMenu = (QMenu*)ui->menubar->addMenu( new QMenu( "MyMenu" ) );
  QMenu* pMyMenu = ui->menubar->addMenu( new QMenu( "MyMenu" ) )->menu();
  QAction* pMyAction = new QAction( "MyAction" );
  pMyMenu->addAction( pMyAction) ;

  //Get actions
  //Don't use follow
  //QMenu* pOption = (QMenu*)ui->menubar->actions().at(0);
  QMenu* pOption = ui->menubar->actions().at(0)->menu();
  qDebug( "%s" , pOption->title().toLocal8Bit().data() );
  //
  QMenu* pGroup = pOption->actions().at(0)->menu();
  qDebug( "%s" , pGroup->title().toLocal8Bit().data() );
  //
  qDebug( "%s" , pGroup->actions().at(0)->text().toLocal8Bit().data() );
  qDebug( "%s" , pGroup->actions().at(1)->text().toLocal8Bit().data() );
  qDebug( "%s" , pOption->actions().at(1)->text().toLocal8Bit().data() );

  //Bind event
  connect( pGroup->actions().at(0) , &QAction::triggered , this , &MainWindow::onAction1Triggered);
  connect( pGroup->actions().at(1) , &QAction::triggered , this , &MainWindow::onAction2Triggered);
  connect( pOption->actions().at(1) , &QAction::triggered , this , &MainWindow::onAction3Triggered);
  connect( pMyAction , &QAction::triggered , this , &MainWindow::onMyActionTriggered);
}

範例的開頭會手動新增"MyMenu"與"MyAction",這和 UI 的操作時不一樣,並不會自動判定是 QMenu 與 QAction ,所以要自己指名,在 addMenu() 的時候會回傳新增的 QMenu ,但會發現回傳的型別是 QAction ,這裡一定要注意 QAction  與 QMenu 並不是繼承關係,但是雙方卻互相提供轉型的 function ,範例透過 menu() 來將 QAction  轉型回 QMenu ,千萬別用 C 的轉型硬幹。接下來是取得每個 action ,最開始會透過 QMenuBar::actions() ,它回傳的型別是 QList<T> ,這個型別用法跟 std::list<T> 差不多,這裡就不多做說明了,回傳後在透過之前說的轉型來取得 QMenu ,範例透過偵錯訊息將其選項名稱顯示,在"Option"裡的"Group"可以透過現在的 QMenu 裡的 QMenu::actions() 來取得,和之前的原理是一樣的,這樣就可以取得整個樹狀結構的選單。最後是事件綁定的部分,這部分就和一般的事件綁定一樣,只是來源的型別是 QAction 。

  最後要說的是 UI 的物件視窗的問題,不知道是不是 Bug ,如果物件型別是 QAction 的時候,右鍵選單會跳不出來,也無法透過 Delete 鍵來刪除,這會造成無法在 UI 操作的時候作"刪除"的動作。

參考資料

[ doc.qt.io ] QAction Class

相關文章與資料

[ GitLab ] HelloQt

沒有留言:

張貼留言