Qtメインウィンドウへのツールバー実装方法

Qtアプリケーションでよく見かけるツールバーは、メニュー項目へのアクセスをアイコンボタンで高速化する領域である。必須ではないが、ユーザビリティを高める効果が大きい。

最小構成でツールバーを追加する

以下のコードは、QMainWindow派生クラスへシンプルにツールバーを追加する例である。

// ToolbarWindow.h
#pragma once
#include <QMainWindow>

class ToolbarWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit Toolbaraway(QWidget* parent = nullptr);
    ~Toolbaraway();
};
// ToolbarWindow.cpp
#include "ToolbarWindow.h"
#include <QToolBar>
#include <QAction>
#include <QPushButton>
#include <QIcon>
#include <QSize>

Toolbaraway::Toolbaraway(QWidget* parent)
    : QMainWindow(parent)
{
    // 1. ツールバーオブジェクトの生成
    QToolBar* bar = addToolBar("MainBar");
    bar->setMovable(false);        // ドラッグ移動禁止
    bar->setFloatable(false);      // ウィンドウ化禁止
    bar->setIconSize(QSize(20, 20));

    // 2. 新規作成アクション
    QAction* newAct = new QAction(this);
    newAct->setIcon(QIcon(":/icons/new.png"));
    newAct->setToolTip("Create new document");
    bar->addAction(newAct);

    // 3. 任意のウィジェットも追加可能
    QPushButton* extraBtn = new QPushButton("Extra", this);
    bar->addWidget(extraBtn);
}

Toolbaraway::~Toolbaraway() = default;
// main.cpp
#include <QApplication>
#include "ToolbarWindow.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    Toolbaraway win;
    win.show();
    return app.exec();
}

Notepadスタイルの完成形

実践的なエディタでは、メニュー/ツールバー/アクションを整理して管理する。以下はその設計例である。

// NotepadMain.h
#pragma once
#include <QMainWindow>
#include <QMenuBar>
#include <QToolBar>
#include <QAction>

class NotepadMain : public QMainWindow
{
    Q_OBJECT
public:
    static NotepadMain* create();
    ~NotepadMain();

private:
    explicit NotepadMain(QWidget* parent = nullptr);
    bool build();               // 構築処理
    bool setupMenuBar();        // メニューバー
    bool setupToolBar();        // ツールバー

    bool addFileMenu(QMenuBar*);
    bool addEditMenu(QMenuBar*);
    bool addFormatMenu(QMenuBar*);
    bool addViewMenu(QMenuBar*);
    bool addHelpMenu(QMenuBar*);

    bool addFileActions(QToolBar*);

    bool makeAction(QAction*&, const QString& text, int shortcut = 0);
    bool makeAction(QAction*&, const QString& tip, const QString& icon);
};
// NotepadMain.cpp
#include "NotepadMain.h"
#include <QKeySequence>

NotepadMain* NotepadMain::create()
{
    NotepadMain* instance = new NotepadMain;
    if (!instance || !instance->build()) {
        delete instance;
        return nullptr;
    }
    return instance;
}

NotepadMain::NotepadMain(QWidget* parent)
    : QMainWindow(parent)
{
}

bool NotepadMain::build()
{
    return setupMenuBar() && setupToolBar();
}

bool NotepadMain::setupMenuBar()
{
    QMenuBar* mb = menuBar();
    return addFileMenu(mb)
        && addEditMenu(mb)
        && addFormatMenu(mb)
        && addViewMenu(mb)
        && addHelpMenu(mb);
}

bool NotepadMain::setupToolBar()
{
    QToolBar* tb = addToolBar("FileTool");
    tb->setMovable(false);
    tb->setFloatable(false);
    tb->setIconSize(QSize(16, 16));
    return addFileActions(tb);
}

// ---------- File メニュー ----------
bool NotepadMain::addFileMenu(QMenuBar* mb)
{
    QMenu* menu = new QMenu("File(&F)");
    QAction* act = nullptr;

    makeAction(act, "New(&N)", Qt::CTRL + Qt::Key_N); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Open(&O)...", Qt::CTRL + Qt::Key_O); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Save(&S)", Qt::CTRL + Qt::Key_S); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Save As(&A)..."); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Print(&P)...", Qt::CTRL + Qt::Key_P); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Exit(&X)"); menu->addAction(act);

    mb->addMenu(menu);
    return true;
}

// ---------- Edit メニュー ----------
bool NotepadMain::addEditMenu(QMenuBar* mb)
{
    QMenu* menu = new QMenu("Edit(&E)");
    QAction* act = nullptr;

    makeAction(act, "Undo(&U)", Qt::CTRL + Qt::Key_Z); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Redo(&R)", Qt::CTRL + Qt::Key_Y); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Cut(&T)", Qt::CTRL + Qt::Key_X); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Copy(&C)", Qt::CTRL + Qt::Key_C); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Paste(&P)", Qt::CTRL + Qt::Key_V); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Delete(&L)", Qt::Key_Delete); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Find(&F)...", Qt::CTRL + Qt::Key_F); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Replace(&R)...", Qt::CTRL + Qt::Key_H); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Goto(&G)", Qt::CTRL + Qt::Key_G); menu->addAction(act);
    menu-&>addSeparator();
    makeAction(act, "Select All(&A)", Qt::CTRL + Qt::Key_A); menu->addAction(act);

    mb->addMenu(menu);
    return true;
}

// ---------- Format メニュー ----------
bool NotepadMain::addFormatMenu(Q(QMenuBar* mb)
{
    QMenu* menu = new QMenu("Format(&O)");
    QAction* act = nullptr;
    makeAction(act, "Auto Wrap(&W)"); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Font(&F)..."); menu->addAction(act);
    mb->addMenu(menu);
    return true;
}

// ---------- View メニュー ----------
bool NotepadMain::addViewMenu(QMenuBar* mb)
{
    QMenu* menu = new QMenu("View(&V)");
    QAction* act = nullptr;
    makeAction(act, "Tool Bar(&T)"); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "Status Bar(&S)"); menu->addAction(act);
    mb->addMenu(menu);
    return true;
}

// ---------- Help メニュー ----------
bool NotepadMain::addHelpMenu(QMenuBar* mb)
{
    QMenu* menu = new QMenu("Help(&H)");
    QAction* act = nullptr;
    makeAction(act, "User Manual"); menu->addAction(act);
    menu->addSeparator();
    makeAction(act, "About Notepad..."); menu->addAction(act);
    mb->addMenu(menu);
    return true;
}

// ---------- ツールバーアクション ----------
bool NotepadMain::addFileActions(QToolBar* tb)
{
    QAction* act = nullptr;
    makeAction(act, "New", ":/icons/new.png"); tb->addAction(act);
    makeAction(act, "Open", ":/icons/open.png"); tb->addAction(act);
    makeAction(act, "Save", ":/icons/save.png"); tb->addAction(act);
    makeAction(act, "Save As", ":/icons/saveas.png"); tb->addAction(act);
    makeAction(act, "Print", ":/icons/print.png"); tb->addAction(act);
    makeAction(act, "Undo", ":/icons/undo.png"); tb->addAction(act);
    makeAction(act, "Redo", ":/icons/redo.png"); tb->addAction(act);
    return true;
}

// ---------- アクション生成補助 ----------
bool NotepadMain::makeAction(QAction*& act, const QString& text, int key)
{
    act = new QAction(text, this);
    if (act) act->setShortcut(QKeySequence(key));
    return act != nullptr;
}

bool NotepadMain::makeAction(QAction*& act, const QString& tip, const QString& icon)
{
    act = new QAction(this);
    if (act) {
        act->setToolTip(tip);
        act->setIcon(QIcon(icon));
    }
    return act != nullptr;
}

NotepadMain::~NotepadMain() = default;
// main.cpp
#include <QApplication>
#include "NotepadMain.h"

int main(int argc, char* argv[])
{
    QApplication app(argc, argv);
    NotepadMain* mainWin = NotepadMain::create();
    if (mainWin) {
        mainWin->show();
        int ret = app.exec();
        delete mainWin;
        return ret;
    }
    return -1;
}

タグ: Qt QToolBar QAction QMainWindow GUI開発

6月24日 17:04 投稿