C/C++ Qt ToolBar menu component application

Posted by DWaller10 on Tue, 23 Nov 2021 10:32:01 +0100

ToolBar toolbar is widely used in all form applications. Using ToolBar can well standardize the classification of menu functions. Users can choose different functions according to the menu bar. Qt has its own ToolBar component by default. When we create a form in the default way, the ToolBar is added to the form. Generally, it exists in the object menu bar in the form of qttoolbar, As shown below.

During the development of QToolBar component, I encountered the following functions, which can basically meet most development requirements. Here is a summary.

There are many ways to define the ToolBar component on the top ToolBar. We can generate it directly through code or drag and drop it using the graphical interface UI, but the code time is more flexible. The ToolBar component can show a variety of forms

First, let's look at a simple generation case. In the following code, we can place ToolBar components in four different directions through the property setAllowedAreas()

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
#include <QMenuBar>
#include <QToolBar>

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);

// ----------------------------------------------------------
// Create menu bar
    QMenuBar *bar = menuBar();
    this->setMenuBar(bar);                      // Place the menu bar in the main window
    QMenu * fileMenu = bar->addMenu("file");     // Create parent node

    // Add submenu
    QAction *newAction = fileMenu->addAction("new file");     // set name
    //newAction->setIcon(QIcon("://image/1.ico"));           //  Set available icons

    fileMenu->addSeparator();                                // Add split line
    QAction *openAction = fileMenu->addAction("Open file");     // set name
    //openAction->setIcon(QIcon("://image/2.ico"));          //  Set available icons

// ----------------------------------------------------------
//Create toolbar
    QToolBar *toolBar = new QToolBar(this);  // Create toolbar
    addToolBar(Qt::LeftToolBarArea,toolBar); // Set default docking range [default docking left]

    toolBar->setAllowedAreas(Qt::TopToolBarArea |Qt::BottomToolBarArea);   // Allow drag up and down
    toolBar->setAllowedAreas(Qt::LeftToolBarArea |Qt::RightToolBarArea);   // Allow drag left and right

    toolBar->setFloatable(false);       // Set whether to float
    toolBar->setMovable(false);         // Set the toolbar not to be moved

    // Add menu item to toolbar
    toolBar->addAction(newAction);
    toolBar->addSeparator();
    toolBar->addAction(openAction);

// By : LyShark
// https://www.cnblogs.com/lyshark
// ----------------------------------------------------------
// Binding slot function
    connect(newAction,&QAction::triggered,this,[=](){
        std::cout << "new action" << std::endl;
    });

    connect(openAction,&QAction::triggered,this,[=](){
        std::cout << "open action" << std::endl;
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}

Then, a top menu bar is implemented in the form of code, in which SetIcon(QIcon("://image/1.ico")) can be used; To specify the icon, you can also use setShortcut(Qt::CTRL | Qt::Key_C); Specify a special shortcut key for it.

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
#include <QMenuBar>
#include <QToolBar>

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);

// ----------------------------------------------------------
// Create menu bar
    QMenuBar *bar = menuBar();
    this->setMenuBar(bar);  //Place the menu bar in the main window
    QMenu * fileMenu = bar->addMenu("file");

// By : LyShark
// https://www.cnblogs.com/lyshark
    // Add submenu
    QAction *newAction = fileMenu->addAction("new file");      // Add name
    newAction->setIcon(QIcon(":/image/1.ico"));              // Set ICO Icon
    newAction->setShortcut(Qt::CTRL | Qt::Key_A);            // Set shortcut key ctrl+a

    fileMenu->addSeparator();                                // Add split line

    QAction *openAction = fileMenu->addAction("Open file");
    openAction->setIcon(QIcon(":/image/2.ico"));
    openAction->setShortcut(Qt::CTRL | Qt::Key_C);          // Set shortcut key ctrl+c

// ----------------------------------------------------------
// Create toolbar (can be shielded, and the control field at the bottom will be lost after shielding)

    QToolBar *toolBar = new QToolBar(this);       // Create toolbar
    addToolBar(Qt::BottomToolBarArea,toolBar);    // Set the default docking range (docked at the bottom)
    toolBar->setFloatable(false);                 // Set whether to float to false
    toolBar->setMovable(false);                   // Set the toolbar not to be moved

    // Add menu item to toolbar
    toolBar->addAction(newAction);               // Toolbar add [new file]
    toolBar->addSeparator();                     // Add split line
    toolBar->addAction(openAction);              // Add [open file]

// ----------------------------------------------------------
// Binding signals and slots
   connect(newAction,&QAction::triggered,this,[=](){
       std::cout << "new file slot" << std::endl;
   });

   connect(openAction,&QAction::triggered,this,[=](){
       std::cout << "open file slot" << std::endl;
   });
}

MainWindow::~MainWindow()
{
    delete ui;
}

Realize the secondary menu of the top menu bar. The secondary top menu is completely consistent with the primary menu, but it is extended on the basis of the primary menu. The following code defines a secondary menu.

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <iostream>
#include <QMenuBar>
#include <QToolBar>

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);

// ----------------------------------------------------------
// Multi layer menu navigation bar
       QMenuBar *MainMenu = new QMenuBar(this);
       this->setMenuBar(MainMenu);

       // 1. Define parent menu
       QMenu *EditMenu = MainMenu->addMenu("edit");

       // 1.1 define the submenu under EditMemu
       QAction *text = new QAction(EditMenu);
       text->setText("Edit file");                     // Set text content
       text->setShortcut(Qt::CTRL | Qt::Key_A);      // Set shortcut key ctrl+a
       text->setIcon(QIcon(":/image/1.ico"));        // Add Icon
       EditMenu->addAction(text);

       EditMenu->addSeparator();                      // Add a dotted line between the configuration mode and the edit file

       QAction *option = new QAction(EditMenu);
       option->setText("Configuration mode");
       option->setIcon(QIcon(":/image/2.ico"));
       EditMenu->addAction(option);

       // 1.1.2 define submenus under Option configuration mode
       QMenu *childMenu = new QMenu();
       QAction *set_file = new QAction(childMenu);
       set_file->setText("Set file content");
       set_file->setIcon(QIcon(":/image/3.ico"));

       childMenu->addAction(set_file);

       QAction *read_file = new QAction(childMenu);
       read_file->setText("Read file contents");
       read_file->setIcon(QIcon(":/image/2.ico"));
       childMenu->addAction(read_file);
// ----------------------------------------------------------
// Register menu to form
// By : LyShark
// https://www.cnblogs.com/lyshark

       // First, register childMenu in option
       option->setMenu(childMenu);
       // Then add childMenu to EditMenu
       EditMenu->addMenu(childMenu);

// ----------------------------------------------------------
// Binding signals and slots
       connect(text,&QAction::triggered,this,[=](){
           std::cout << "edit file slot" << std::endl;
       });

       connect(set_file,&QAction::triggered,this,[=](){
           std::cout << "set file slot" << std::endl;
       });

       connect(read_file,&QAction::triggered,this,[=](){
          std::cout << "read file slot" << std::endl;
       });
}

MainWindow::~MainWindow()
{
    delete ui;
}

The menu in Qt can also pop up anywhere. For example, we can bind the customContextMenuRequested() event to the main window, and right-click anywhere on the form to pop up the menu bar. The code is as follows.

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMenuBar>
#include <iostream>

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setContextMenuPolicy(Qt::CustomContextMenu);
}

MainWindow::~MainWindow()
{
    delete ui;
}

// Right click on the main interface - > go to the customContextMenuRequested slot
// By : LyShark
// https://www.cnblogs.com/lyshark
void MainWindow::on_MainWindow_customContextMenuRequested(const QPoint &pos)
{
    // Create menu object
    QMenu *pMenu = new QMenu(this);

    QAction *pNewTask = new QAction(tr("newly build"), this);
    QAction *pEditTask = new QAction(tr("edit"), this);
    QAction *pDeleteTask = new QAction(tr("delete"), this);

    // Set attribute value No.: 1 = > New 2 = > Set 3 = > delete
    pNewTask->setData(1);
    pEditTask->setData(2);
    pDeleteTask ->setData(3);

    // Add the QAction object to the menu
    pMenu->addAction(pNewTask);
    pMenu->addAction(pEditTask);
    pMenu->addAction(pDeleteTask);

    // Add Icon
    pNewTask->setIcon(QIcon(":/image/1.ico"));
    pEditTask->setIcon(QIcon(":/image/2.ico"));
    pDeleteTask->setIcon(QIcon(":/image/3.ico"));

    // Connect right mouse click signal
    connect(pNewTask, SIGNAL(triggered()), this, SLOT(onTaskBoxContextMenuEvent()));
    connect(pEditTask, SIGNAL(triggered()), this, SLOT(onTaskBoxContextMenuEvent()));
    connect(pDeleteTask, SIGNAL(triggered()), SLOT(onTaskBoxContextMenuEvent()));

    // Displays the menu where the right mouse button is clicked
    pMenu->exec(QCursor::pos());

    //Free memory
    QList<QAction*> list = pMenu->actions();
    foreach (QAction* pAction, list) delete pAction;
    delete pMenu;
}

// Process the transmitted signal
void MainWindow::onTaskBoxContextMenuEvent()
{
    // This - > sender () is the signal sender QAction
    QAction *pEven = qobject_cast<QAction *>(this->sender());

    // Get No.: 1 = > New 2 = > Set 3 = > delete
    int iType = pEven->data().toInt();

    switch (iType)
    {
    case 1:
        std::cout << "New task" << std::endl;
        break;
    case 2:
        std::cout << "Set task" << std::endl;
        break;
    case 3:
        std::cout << "Delete task" << std::endl;
        break;
    default:
        break;
    }
}

You can also set the menu at the top through bar - > setvisible (false); Property to hide it. Only one ToolBar control field is displayed externally. Only ICO icon and bottom text description are retained in the ToolBar control bar, which can make it more refreshing.

#include "mainwindow.h"
#include "ui_mainwindow.h"

#include <QMenuBar>
#include <QToolBar>
#include <iostream>

MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow)
{
    ui->setupUi(this);

// ----------------------------------------------------------
    // Hide the right-click menu on the menu bar
    this->setContextMenuPolicy(Qt::NoContextMenu);

    // Create the base top menu and hide it
    QMenuBar *bar = menuBar();
    this->setMenuBar(bar);
    QMenu * fileMenu = bar->addMenu("Ptr");
    bar->setVisible(false);                 // Hide menu

    // Add submenu
    QAction *NewAction = fileMenu->addAction("new file");
    QAction *OpenAction = fileMenu->addAction("Open file");
    QAction *ReadAction = fileMenu->addAction("Read in file");

    // Set icons separately
    NewAction->setIcon(QIcon(":/image/1.ico"));
    OpenAction->setIcon(QIcon(":/image/2.ico"));
    ReadAction->setIcon(QIcon(":/image/3.ico"));

    // Create toolbar
    QToolBar *toolBar = new QToolBar(this);
    addToolBar(Qt::TopToolBarArea,toolBar);

    // Add menu items to the toolbar in turn
    toolBar->addAction(NewAction);
    toolBar->addAction(OpenAction);
    toolBar->addAction(ReadAction);

    // Set the prohibit movement property, and the toolbar is pasted above by default
    toolBar->setFloatable(false);
    toolBar->setMovable(false);
    toolBar->setToolButtonStyle(Qt::ToolButtonTextUnderIcon);

// ----------------------------------------------------------
// Binding slot function
// By : LyShark
// https://www.cnblogs.com/lyshark
    connect(NewAction,&QAction::triggered,this,[=](){
        std::cout << "new action" << std::endl;
    });

    connect(OpenAction,&QAction::triggered,this,[=](){
        std::cout << "open action" << std::endl;
    });

    connect(ReadAction,&QAction::triggered,this,[=](){
        std::cout << "read action" << std::endl;
    });
}

MainWindow::~MainWindow()
{
    delete ui;
}