メニューの例

Menusの例では、メイン・ウィンドウ・アプリケーションでのメニューの使い方を説明します。

メニュー・ウィジェットには、メニュー・バー内のプル・ダウン・メニューと、スタンドアロンのコンテキスト・メニューがあります。プルダウン・メニューは、ユーザーがそれぞれの項目をクリックするか、指定されたショートカット・キーを押すと、メニュー・バーに表示されます。コンテキストメニューは通常、特別なキーボードキーや右クリックによって呼び出されます。

メニューはアクションアイテムのリストから構成されます。アプリケーションでは、メニュー、ツールバーボタン、キーボードショートカットを介して、多くの一般的なコマンドを呼び出すことができます。ユーザーは、使用されるユーザーインターフェースに関係なく、コマンドが同じ方法で実行されることを期待するので、各コマンドをアクションとして表現することは有用である。

Menusの例は、QMainWindow クラスから派生したMainWindow という1つのクラスで構成されています。アプリケーションでアクション・アイテムの1つを選択すると、そのアイテムのパスが中央のウィジェットに表示されます。

MainWindowクラスの定義

QMainWindow はメイン・アプリケーション・ウィンドウを提供し、メニュー・バー、ツール・バー、ドック・ウィジェット、ステータス・バーが大きな中央ウィジェットを囲んでいます。

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow();

protected:
#ifndef QT_NO_CONTEXTMENU
    void contextMenuEvent(QContextMenuEvent *event) override;
#endif // QT_NO_CONTEXTMENU

この例では、プルダウン・メニューとコンテキスト・メニューの実装方法を説明します。カスタム・コンテキスト・メニューを実装するには、QWidgetcontextMenuEvent() 関数を再実装して、メイン・ウィンドウのコンテキスト・メニュー・イベントを受け取る必要があります。

private slots:
    void newFile();
    void open();
    void save();
    void print();
    void undo();
    void redo();
    void cut();
    void copy();
    void paste();
    void bold();
    void italic();
    void leftAlign();
    void rightAlign();
    void justify();
    void center();
    void setLineSpacing();
    void setParagraphSpacing();
    void about();
    void aboutQt();

また、ユーザーがメニュー・エントリーをアクティブにしたときに応答するプライベート・スロットのコレクションを実装しなければなりません。これらのスロットは、メイン・ウィンドウの中央ウィジェットにアクションのパスを表示するだけの些細なものなので、このドキュメントでは割愛します。

private:
    void createActions();
    void createMenus();

様々なアクションを作成し、それらをメニューに追加し、メインウィンドウのメニューバーにメニューを挿入するために、2つのプライベート便利関数を実装することで、コンストラクタを簡素化することにしました。

    QMenu *fileMenu;
    QMenu *editMenu;
    QMenu *formatMenu;
    QMenu *helpMenu;
    QActionGroup *alignmentGroup;
    QAction *newAct;
    QAction *openAct;
    QAction *saveAct;
    QAction *printAct;
    QAction *exitAct;
    QAction *undoAct;
    QAction *redoAct;
    QAction *cutAct;
    QAction *copyAct;
    QAction *pasteAct;
    QAction *boldAct;
    QAction *italicAct;
    QAction *leftAlignAct;
    QAction *rightAlignAct;
    QAction *justifyAct;
    QAction *centerAct;
    QAction *setLineSpacingAct;
    QAction *setParagraphSpacingAct;
    QAction *aboutAct;
    QAction *aboutQtAct;
    QLabel *infoLabel;
};

最後に、アプリケーション・ワイド・スコープで、さまざまなメニューとアクション、シンプルな情報ラベルを宣言します。

QMenu クラスは、メニュー・バー、コンテキスト・メニュー、その他のポップアップ・メニューで使用するメニュー・ウィジェットを提供し、QAction クラスは、ウィジェットに挿入できる抽象的なユーザー・インターフェース・アクションを提供します。

例えば、Left Align アクション、Right Align アクション、Justify アクション、Center アクションがあり、これらのアクションのうち1つだけを常にアクティブにしたい場合です。これを実現する簡単な方法の1つは、QActionGroup クラスを使ってアクションをアクション グループにまとめることです。

MainWindowクラスの実装

コンストラクタでは、まずQWidget を作成し、メインウィンドウの中心ウィジェットにします。メイン・ウィンドウはウィジェット・ポインタの所有権を持ち、適切なタイミングでそれを削除することに注意してください。

MainWindow::MainWindow()
{
    QWidget *widget = new QWidget;
    setCentralWidget(widget);

    QWidget *topFiller = new QWidget;
    topFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    infoLabel = new QLabel(tr("<i>Choose a menu option, or right-click to "
                              "invoke a context menu</i>"));
    infoLabel->setFrameStyle(QFrame::StyledPanel | QFrame::Sunken);
    infoLabel->setAlignment(Qt::AlignCenter);

    QWidget *bottomFiller = new QWidget;
    bottomFiller->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);

    QVBoxLayout *layout = new QVBoxLayout;
    layout->setContentsMargins(5, 5, 5, 5);
    layout->addWidget(topFiller);
    layout->addWidget(infoLabel);
    layout->addWidget(bottomFiller);
    widget->setLayout(layout);

次に、情報ラベルと上下のフィラーを作成し、中央ウィジェットにインストールするレイアウトに追加します。QMainWindow オブジェクトには、独自にカスタマイズされたレイアウトが付属しています。実際のメイン・ウィンドウにレイアウトを設定したり、メイン・ウィンドウを親としてレイアウトを作成したりすることはエラーと見なされます。必ず、セントラル・ウィジェットに独自のレイアウトを設定してください。

    createActions();
    createMenus();

    QString message = tr("A context menu is available by right-clicking");
    statusBar()->showMessage(message);

    setWindowTitle(tr("Menus"));
    setMinimumSize(160, 160);
    resize(480, 320);
}

アクションとメニューを作成するために、2つの便利な関数を呼び出します:createActions()createMenus() 。これらについては、後ほど説明します。

QMainWindow statusBar() 関数は、メイン・ウィンドウのステータス・バーを返します(ステータス・バーが存在しない場合、この関数は空のステータス・バーを作成して返します)。ステータスバーとウィンドウタイトルを初期化し、ウィンドウを適切なサイズにリサイズし、メインウィンドウが指定されたサイズより小さくリサイズできないようにします。

では、さまざまなアクションを作成するcreateActions() コンビニエンス関数を詳しく見てみましょう:

void MainWindow::createActions()
{
    newAct = new QAction(QIcon::fromTheme(QIcon::ThemeIcon::DocumentNew),
                         tr("&New"), this);
    newAct->setShortcuts(QKeySequence::New);
    newAct->setStatusTip(tr("Create a new file"));
    connect(newAct, &QAction::triggered, this, &MainWindow::newFile);
    ...

QAction オブジェクトには、アイコン、テキスト、ショートカット、ステータス・チップ、"What's This? "テキスト、ツールチップが含まれます。これらのほとんどはコンストラクタで設定できますが、提供されている便利な関数を使用して個別に設定することもできます。

createActions() 関数では、まずnewAct アクションを作成し、テキストと、テーマのアイコン定数のいずれかを使用してアイコンを渡します。QAction::setShortcut() 関数を使用してCtrl+N をそのショートカットにし、QAction::setStatusTip() 関数を使用してステータスチップを設定します(ステータスチップは、アクションのトップレベル親ウィジェットが提供するすべてのステータスバーに表示されます)。また、triggered() シグナルをnewFile() スロットに接続します。

残りのアクションも同様の方法で作成されます。詳細はソースコードを参照してください。

    alignmentGroup = new QActionGroup(this);
    alignmentGroup->addAction(leftAlignAct);
    alignmentGroup->addAction(rightAlignAct);
    alignmentGroup->addAction(justifyAct);
    alignmentGroup->addAction(centerAct);
    leftAlignAct->setChecked(true);
}

Left AlignRight AlignJustifyCenter アクションを作成したら、前述のアクショングループも作成します。

各アクションは、QActionGroupaddAction() 関数を使用してグループに追加される。アクションは、グループを親として作成することでもグループに追加できることに注意してください。アクショングループはデフォルトで排他的であるため、グループ内のアクションのうち1つだけが一度にチェックされます(これはQActionGroup::setExclusive ()関数を使用して変更できます)。

すべてのアクションが作成されたら、createMenus() 関数を使用してアクションをメニューに追加し、メニューをメニューバーに挿入します:

void MainWindow::createMenus()
{
    fileMenu = menuBar()->addMenu(tr("&File"));
    fileMenu->addAction(newAct);
    fileMenu->addAction(openAct);
    fileMenu->addAction(saveAct);
    fileMenu->addAction(printAct);
    fileMenu->addSeparator();
    fileMenu->addAction(exitAct);

    editMenu = menuBar()->addMenu(tr("&Edit"));
    editMenu->addAction(undoAct);
    editMenu->addAction(redoAct);
    editMenu->addSeparator();
    editMenu->addAction(cutAct);
    editMenu->addAction(copyAct);
    editMenu->addAction(pasteAct);
    editMenu->addSeparator();

    helpMenu = menuBar()->addMenu(tr("&Help"));
    helpMenu->addAction(aboutAct);
    helpMenu->addAction(aboutQtAct);

QMenuBar addMenu()関数は、与えられたタイトルの新しい をメニューバーに追加します(メニューバーがメニューの所有権を持つことに注意してください)。各アクションを対応するメニューに追加するには、 の () 関数を使用します。QMenu QWidget addAction

また、QMenu クラスは、与えられたテキストやアイコンから新しいアクションを作成したり追加したりする便利な関数addAction() をいくつか提供しています。また、新しいアクションのtriggered() シグナルに自動的に接続するメンバと、QKeySequence インスタンスで表されるショートカットを指定することもできます。

QMenu::addSeparator() 関数は、新しいセパレーターアクション、つまりQAction::isSeparator() が true を返すアクションを作成し、返します。そして、新しいアクションをメニューのアクションリストに追加します。

    formatMenu = editMenu->addMenu(tr("&Format"));
    formatMenu->addAction(boldAct);
    formatMenu->addAction(italicAct);
    formatMenu->addSeparator()->setText(tr("Alignment"));
    formatMenu->addAction(leftAlignAct);
    formatMenu->addAction(rightAlignAct);
    formatMenu->addAction(justifyAct);
    formatMenu->addAction(centerAct);
    formatMenu->addSeparator();
    formatMenu->addAction(setLineSpacingAct);
    formatMenu->addAction(setParagraphSpacingAct);
}

Format 。まず、QMenuaddMenu() 関数を使って、Edit Menu のサブメニューとして追加されています。次に、整列アクションを見てください:createActions() 関数の中で、leftAlignActrightAlignActjustifyActcenterAct のアクションをアクショングループに追加しました。とはいえ、各アクションを個別にメニューに追加しなければなりません。

#ifndef QT_NO_CONTEXTMENU
void MainWindow::contextMenuEvent(QContextMenuEvent *event)
{
    QMenu menu(this);
    menu.addAction(cutAct);
    menu.addAction(copyAct);
    menu.addAction(pasteAct);
    menu.exec(event->globalPos());
}
#endif // QT_NO_CONTEXTMENU

カスタム・コンテキスト・メニューを提供するには、QWidget'のcontextMenuEvent() 関数を再実装して、ウィジェットのコンテキスト・メニュー・イベントを受け取る必要があります(デフォルトの実装では、これらのイベントを単に無視することに注意してください)。

このようなイベントを受信するたびに、CutCopyPaste アクションを含むメニューを作成します。コンテキスト・メニューは、popup() 関数を使って非同期に実行することも、exec() 関数を使って同期的に実行することもできます。この例では、exec ()関数を使用してメニューを表示することにしました。イベントの位置を引数として渡すことで、コンテキストメニューが期待通りの位置に表示されるようにしています。

プロジェクト例 @ code.qt.io

©2024 The Qt Company Ltd. ここに含まれるドキュメントの著作権は、それぞれの所有者に帰属します。 本書で提供されるドキュメントは、Free Software Foundation が発行したGNU Free Documentation License version 1.3に基づいてライセンスされています。 Qtおよびそれぞれのロゴは、フィンランドおよびその他の国におけるThe Qt Company Ltd.の 商標です。その他すべての商標は、それぞれの所有者に帰属します。