質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

Q&A

解決済

1回答

1704閲覧

QtでQMenuBarの背景色を変えたい

nabla

総合スコア6

Qt

QtはGUIプログラムの開発で広く使われているクロスプラットフォーム開発のフレームワークです。

C++

C++はC言語をもとにしてつくられた最もよく使われるマルチパラダイムプログラミング言語の1つです。オブジェクト指向、ジェネリック、命令型など広く対応しており、多目的に使用されています。

Qt Creator

Qt Creatorは、Qtアプリケーションを開発するための開発統合環境(IDE)です。

0グッド

0クリップ

投稿2022/02/24 10:20

編集2022/02/25 10:47

前提・実現したいこと

QtでQMenuWindowを継承したウィンドウを作っているのですが、そのメニューバーの背景色を元の白色から灰色(ちょうどQt Creatorのメニューバーの色)に変更したいです。

発生している問題

QPaletteを用いて、変更したいのですがその方法が分かりません。

試したこと

次のようにsetPalette()を使用しましたが、変化はありませんでした。

c++

1qDebug() << menuBar()->foregroundRole(); //ButtonText 2qDebug() << menuBar()->backgroundRole(); //Button 3qDebug() << menuBar()->palette(); //変更前のPalette 4 5QPalette palette; 6palette.setColor(QPalette::ColorRole::Button, Qt::black); 7 8menuBar()->setPalette(palette); 9 10qDebug() << menuBar()->palette(); //変更後のPalette

出力は以下の通りでした。

txt

1//変更前 2QPalette(resolve=0x0) 3//変更後 4QPalette(resolve=0x10000080000400,"Window:[Active:#ff000000,Disabled:#ff000000,Inactive:#ff000000]")

値は変わっていますが、メニューバーは変化がありませんでした。ほかにもQPalette::ColorRoleをWindowやBaseでやっても変化はありませんでした。

QWidgetクラスのドキュメントのQPalette項目を見てみると以下のようにありました。

The default depends on the system environment. QApplication maintains a system/theme palette which serves as a default for all widgets. There may also be special palette defaults for certain types of widgets (e.g., on Windows Vista, all classes that derive from QMenuBar have a special default palette). You can also define default palettes for widgets yourself by passing a custom palette and the name of a widget to QApplication::setPalette(). Finally, the style always has the option of polishing the palette as it's assigned (see QStyle::polish()).

QMenuBarクラスには特別にデフォルトのQPaletteが設定されているらしい??そこで書いて通りに、QMenuBarのPaletteを上書きしたく、次のようにしました。

C++

1qDebug() << QApplication::palette("QMenuBar"); //変更前のQMenuBarのPalette 2 3QPalette palette; 4palette.setColor(QPalette::ColorRole::Button, Qt::black); 5QApplication::setPalette(palette, "QMenuBar"); 6 7qDebug() << QApplication::palette("QMenuBar"); //変更後

しかし、メニューバーの色は変わりませんでした。出力は以下の通りです

txt

1//変更前 2QPalette(resolve=0x77ffffa7fffdffff," 3WindowText:[Active:#ff000000,Disabled:#ff6d6d6d,Inactive:#ff000000], 4Button:[Active:#fff0f0f0,Disabled:#fff0f0f0,Inactive:#fff0f0f0], 5Light:[Active:#ffffffff,Disabled:#ffffffff,Inactive:#ffffffff], 6Midlight:[Active:#ffe3e3e3,Disabled:#fff7f7f7,Inactive:#ffe3e3e3], 7Dark:[Active:#ffa0a0a0,Disabled:#ffa0a0a0,Inactive:#ffa0a0a0], 8Mid:[Active:#ffa0a0a0,Disabled:#ffa0a0a0,Inactive:#ffa0a0a0], 9Text:[Active:#ff000000,Disabled:#ff6d6d6d,Inactive:#ff000000], 10BrightText:[Active:#ffffffff,Disabled:#ffffffff,Inactive:#ffffffff], 11ButtonText:[Active:#ff000000,Disabled:#ff787878,Inactive:#ffa0a0a0], 12Base:[Active:#ffffffff,Disabled:#fff0f0f0,Inactive:#ffffffff], 13Window:[Active:#fff0f0f0,Disabled:#fff0f0f0,Inactive:#fff0f0f0], 14Shadow:[Active:#ff696969,Disabled:#ff000000,Inactive:#ff696969], 15Highlight:[Active:#ff0078d7,Disabled:#ff0078d7,Inactive:#ff0078d7], 16HighlightedText:[Active:#ffffffff,Disabled:#ff6d6d6d,Inactive:#ffffffff], 17Link:[Active:#ff0000ff,Inactive:#ff0000ff], 18LinkVisited:[Active:#ffff00ff,Inactive:#ffff00ff], 19AlternateBase:[Active:#ffe9e7e3,Disabled:#fff7f7f7,Inactive:#ffe9e7e3], 20ToolTipBase:[Active:#ffffffdc,Disabled:#ffffffdc,Inactive:#ffffffdc], 21ToolTipText:[Active:#ff000000,Disabled:#ff000000,Inactive:#ff000000], 22PlaceholderText:[Active:#80000000,Disabled:#80000000,Inactive:#80000000]") 23//変更後 24QPalette(resolve=0x0)

正しくセットされていない??
他にもmenuWidget()やQMenu自体のPaletteを変更したりしましたが、変更できませんでした。

補足情報(FW/ツールのバージョンなど)

Desktop Qt 6.2.0 MSVC2019 64bit

メニューバーの背景色とは下のQt Creatorでいうと、「ファイル(F)」や「編集(E)」の背景のグレーの部分のことです。

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

デフォルトで使用される Windows 向けのスタイルが Windows のテーマに沿った背景を描画する実装になっているため、パレットの変更ではメニューバーの背景色は変更できないようです。

実際のコードは
https://code.qt.io/cgit/qt/qtbase.git/tree/src/plugins/styles/windowsvista/qwindowsvistastyle.cpp?h=6.2#n1128
の d->drawBackground(); の処理です。

というわけで、この部分の処理を差し替えるような自前のスタイル(QStyle)を作成する必要があります。

実際はさらに一工夫が必要ですが、以下のような QMenuBar のサブクラスを作成し、
QMainWindow で利用することで実現が可能かと思います。
(.ui ファイルを利用している場合には、Promote をする必要があります)

C++

1#ifndef MENUBAR_H 2#define MENUBAR_H 3 4#include <QMenuBar> 5#include <QProxyStyle> 6 7class MenuBarStyle : public QProxyStyle 8{ 9 Q_OBJECT 10public: 11 MenuBarStyle(QStyle *style = nullptr); 12 void drawControl(ControlElement element, const QStyleOption *opt, QPainter *p, const QWidget *w) const override; 13}; 14 15class MenuBar : public QMenuBar 16{ 17 Q_OBJECT 18public: 19 explicit MenuBar(QWidget *parent = nullptr); 20}; 21 22#endif // MENUBAR_H

C++

1#include "menubar.h" 2#include <QPainter> 3#include <QStyleOption> 4 5MenuBarStyle::MenuBarStyle(QStyle *parent) 6 : QProxyStyle(parent) 7{} 8 9void MenuBarStyle::drawControl(ControlElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const 10{ 11 switch (element) { 12 case CE_MenuBarEmptyArea: 13 break; 14 case CE_MenuBarItem: 15 if (const QStyleOptionMenuItem *mbi = qstyleoption_cast<const QStyleOptionMenuItem *>(option)) { 16 bool disabled = !(option->state & State_Enabled); 17 if (mbi->menuItemType == QStyleOptionMenuItem::DefaultItem) 18 break; 19 20 QPalette::ColorRole textRole = disabled ? QPalette::Text : QPalette::ButtonText; 21 QPixmap pix = mbi->icon.pixmap(proxy()->pixelMetric(PM_SmallIconSize, option, widget), QIcon::Normal); 22 23 int alignment = Qt::AlignCenter | Qt::TextShowMnemonic | Qt::TextDontClip | Qt::TextSingleLine; 24 if (!proxy()->styleHint(SH_UnderlineShortcut, mbi, widget)) 25 alignment |= Qt::TextHideMnemonic; 26 27 if (!pix.isNull()) 28 drawItemPixmap(painter, mbi->rect, alignment, pix); 29 else 30 drawItemText(painter, mbi->rect, alignment, mbi->palette, mbi->state & State_Enabled, mbi->text, textRole); 31 } 32 break; 33 default: 34 QProxyStyle::drawControl(element, option, painter, widget); 35 break; 36 } 37} 38 39MenuBar::MenuBar(QWidget *parent) 40 : QMenuBar(parent) 41{ 42 auto p = palette(); 43 p.setColor(QPalette::Window, Qt::transparent); 44 p.setColor(QPalette::Button, Qt::red); 45 p.setColor(QPalette::ButtonText, Qt::white); 46 setPalette(p); 47 setAutoFillBackground(true); 48 auto s = style(); 49 s->setParent(nullptr); 50 setStyle(new MenuBarStyle(s)); 51 s->setParent(this); 52}

投稿2022/02/24 19:54

tasuku.

総合スコア347

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nabla

2022/02/25 01:47

回答ありがとうございます。 提示いただいた方法でメニューバーの色を変更することができました。 まだ詳細は理解できていませんが、いろいろ試してみます。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問