📢 Webサイト閉鎖と移転のお知らせ
このWebサイトは2026年9月に閉鎖いたします。
新しい記事は移転先で追加しております。(旧サイトでは記事を追加しておりません)
細 文字列「__FORCETOC__」を「{{#seo: |title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki |keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 |description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This pag… |
|||
| (同じ利用者による、間の11版が非表示) | |||
| 1行目: | 1行目: | ||
== 概要 == | == 概要 == | ||
Qtにおいて、ウィンドウのメニューバー、ツールバー、ステータスバーの作成手順を記載する。<br> | Qtにおいて、ウィンドウのメニューバー、ツールバー、ステータスバーの作成手順を記載する。<br> | ||
<br><br> | |||
== タイトルバー == | |||
==== アイコン ==== | |||
ウインドウのタイトルバーにアイコンを指定するには、<code>setWindowIcon</code>メソッドを使用する。<br> | |||
<center> | |||
{| class="wikitable" style="background-color:#fefefe;" | |||
|- | |||
! style="background-color:#66CCFF;" | データ | |||
! style="background-color:#66CCFF;" | アイコンの設定例(QIconクラス) | |||
|- | |||
| style="text-align: center;" | 標準画像 || | |||
<syntaxhighlight lang="c++">QIcon Icon = style()->standardIcon(QStyle::SP_MediaPlay); | |||
QApplication::setWindowIcon(Icon);</syntaxhighlight> | |||
|- | |||
| style="text-align: center;" | 標準カーソル || | |||
<syntaxhighlight lang="c++">QCursor Cursor = Qt::WaitCursor; | |||
if(!Cursor.pixmap().isNull()) | |||
{ | |||
QIcon Icon = QIcon(QPixmap(csr.pixmap())); | |||
QApplication::setWindowIcon(Icon); | |||
} | |||
</syntaxhighlight> | |||
|- | |||
| style="text-align: center;" | リソースの指定 || | |||
<syntaxhighlight lang="c++"> | |||
QIcon Icon = QIcon(":/images/mouse.png"); | |||
QApplication::setWindowIcon(Icon); | |||
</syntaxhighlight> | |||
|- | |||
| style="text-align: center;" | ファイルパスの指定 || | |||
<syntaxhighlight lang="c++"> | |||
QIcon Icon = QIcon("C:/temp/testimage.ico"); | |||
QApplication::setWindowIcon(Icon); | |||
</syntaxhighlight> | |||
|} | |||
</center> | |||
<br> | |||
==== タイトルバーの非表示 ==== | |||
<code>setWindowFlags</code>メソッドを使用して、<code>Qt::FramelessWindowHint</code>フラグを設定することにより、ウインドウのタイトルバーが非表示になる。<br> | |||
この<code>Qt::FramelessWindowHint</code>フラグを使用すると、最大化/最小化ボタン、ウインドウの境界線、タイトルバーが非表示になる。<br> | |||
<br> | |||
したがって、このフラグを使用することにより、ウインドウ全体がカスタム外観になり、デフォルトのウインドウ機能が失われる。<br> | |||
また、必要に応じて、これらの機能を再実装することもできる。<br> | |||
<syntaxhighlight lang="c++"> | |||
#include <QGUIApplication> | |||
#include <QMainwindow> | |||
int main(int argc, char *argv[]) | |||
{ | |||
QGUIApplication a(argc, argv); | |||
QMainWindow Window; | |||
// タイトルバーを非表示にする | |||
Window.setWindowFlags(Qt::FramelessWindowHint); | |||
Window.show(); | |||
return a.exec(); | |||
} | |||
</syntaxhighlight> | |||
<br><br> | <br><br> | ||
| 63行目: | 125行目: | ||
メニューを選択してリソースファイルを上書き保存する。<br> | メニューを選択してリソースファイルを上書き保存する。<br> | ||
[ファイル] - [<リソースファイル名>の保存]<br> | [ファイル] - [<リソースファイル名>の保存]<br> | ||
<br> | |||
==== ツールボタンの画像 ==== | |||
ツールバーのツールボタンでは、アイコンとテキストが表示できる。<br> | |||
<br> | |||
ツールボタンは常に固定サイズであり、アイコンの位置はテキストの左または下を指定する。<br> | |||
また、アイコンのサイズも指定できる。<br> | |||
<syntaxhighlight lang="c++"> | |||
std::unique_ptr<QToolButton> pToolBtn = std::make_unique<QToolButton>(); | |||
QIcon Icon = QIcon(style()->standardPixmap(QStyle::SP_TitleBarMenuButton)); | |||
pToolBtn->setIcon(Icon); | |||
pToolBtn->setText(tr("Test")); | |||
pToolBtn->setToolButtonStyle(Qt::ToolButtonTextBesideIcon); | |||
</syntaxhighlight> | |||
<br> | |||
アイコンのサイズを指定しない場合、原画像のサイズで表示する。<br> | |||
プッシュボタンとは異なり、スタイルを指定しない場合はアイコンのみを表示する。<br> | |||
<br> | |||
下表に、ボタンスタイルの定義を示す。<br> | |||
<br> | |||
<u>※注意</u><br> | |||
<u>ツールボタンは、レイアウトの伸縮に影響されずに同じサイズを保持する。</u><br> | |||
<center> | |||
表. ボタンスタイルの定義(enum Qt::ToolButtonStyle)<br> | |||
{| class="wikitable" style="background-color:#fefefe;" | |||
|- | |||
! style="background-color:#00ffff;" | 定義 | |||
! style="background-color:#00ffff;" | 値 | |||
! style="background-color:#00ffff;" | 説明 | |||
|- | |||
| ToolButtonIconOnly || 0 || アイコンのみ | |||
|- | |||
| ToolButtonTextOnly || 1 || テキストのみ | |||
|- | |||
| ToolButtonTextBesideIcon || 2 || アイコンの横にテキスト | |||
|- | |||
| ToolButtonTextUnderIcon || 3 || アイコンの下にテキスト | |||
|- | |||
| ToolButtonFollowStyle || 4 || スタイルに従う | |||
|} | |||
</center> | |||
<br><br> | <br><br> | ||
| 166行目: | 269行目: | ||
</syntaxhighlight> | </syntaxhighlight> | ||
<br><br> | <br><br> | ||
== イベント == | |||
==== リサイズイベント ==== | |||
<code>resizeEvent</code>メソッドは、ウィジェットのサイズが変化した時に発生する。<br> | |||
<syntaxhighlight lang="c++"> | |||
// Mainwindow.h | |||
// ... 略 | |||
protected: | |||
void resizeEvent(QResizeEvent *event); | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// Mainwindow.cpp | |||
// ウインドウの幅と高さをデバッグ出力する | |||
void MainWindow::resizeEvent(QResizeEvent *event) | |||
{ | |||
qDebug("Resize old=%dx%d,new=%dx%d", event->oldSize().width(), event->oldSize().height(), event->size().width(), event->size().height() ); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== クローズイベント ==== | |||
<code>closeEvent</code>メソッドは、タイトルバーの×ボタンを押下した時やcloseメソッドを実行する時に発生する。<br> | |||
<syntaxhighlight lang="c++"> | |||
// Mainwindow.h | |||
// ...略 | |||
protected: | |||
void closeEvent(QCloseEvent *event); | |||
private: | |||
bool checkQuit; | |||
</syntaxhighlight> | |||
<br> | |||
コンストラクタでスイッチ(変数checkQuit)を初期化する。<br> | |||
スイッチをtrueにする時、ウインドウを閉じる直前に確認メッセージのYes / Noメッセージボックスを表示する。<br> | |||
Noを選択する場合、終了処理を行わずに元の画面に戻る。<br> | |||
Yesを選択する場合、ウインドウを閉じて終了する。<br> | |||
<syntaxhighlight lang="c++"> | |||
// Mainwindow.cpp | |||
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) | |||
{ | |||
checkQuit = true; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
<syntaxhighlight lang="c++"> | |||
// Mainwindow.cpp | |||
void MainWindow::closeEvent(QCloseEvent *event) | |||
{ | |||
if(checkQuit) | |||
{ | |||
int ret = QMessageBox::question(this, tr("終了確認"), tr("終了しますか?")); | |||
if(ret == QMessageBox::No) | |||
{ | |||
event->ignore(); | |||
} | |||
} | |||
event->accept(); | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
== ウインドウおよびウィジェットの形状の変更 == | |||
ウインドウおよびプッシュボタン等のウィジェットにおいて、形状を非矩形に変更する、および、背景を画像に変更する手順を記載する。<br> | |||
<br> | |||
==== 非矩形ウインドウ ==== | |||
まず、型抜き用画像を作成する。<br> | |||
型抜き用画像は、ウインドウの形状を表す部分を描画した画像のことであり、画像以外の箇所を透過ピクセルにする。<br> | |||
したがって、型抜き用画像は透過(アルファチャンネル)をサポートするフォーマットで保存する必要がある。<br> | |||
<br> | |||
これは、[https://inkscape.org/ja/ Inkscape](ソフトウェア)を使用して、ウィンドウの形状を描画してPNG形式で保存する方法を推奨する。<br> | |||
<br> | |||
次に、QMainWindowクラスまたはQDialogクラスのコンストラクタにおいて、以下のように記述する。<br> | |||
<syntaxhighlight lang="c++"> | |||
MainWindow::MainWindow() | |||
{ | |||
Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint | Qt::FramelessWindowHint; | |||
setWindowFlags(flags); | |||
QPixmap pixmap("window.png"); | |||
setMask(pixmap.mask()); | |||
// 型抜き画像のサイズに合わせる | |||
resize( 300, 300 ); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== ウインドウおよびウィジェットの外観の変更 ==== | |||
例えば、ウインドウの背景色を変更する場合、QMainWindowクラスまたはQDialogクラスのコンストラクタにおいて、以下のように記述する。 | |||
<syntaxhighlight lang="c++"> | |||
MainWindow::MainWindow() | |||
{ | |||
// 背景色を設定する | |||
setStyleSheet("* {background-color : rgb( 255, 255, 128 )}"); | |||
// 透過率を設定する | |||
setWindowOpacity(0.7); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
また、上記の変更は、Qt Designerから実行することもできる。<br> | |||
Qt Designer画面から、ウインドウまたはウィジェットの[プロパティ] - [styleSheet]項目を選択する。<br> | |||
[スタイルシートを変更]画面が開くので、[〜を追加]プルダウンから"background-color"と"Opacity"のQSSを追加する。<br> | |||
<br> | |||
==== QSSをプロジェクト全体に適用する ==== | |||
一般的に、QSSの設定は各ウィジェットごとに設定するが、プロジェクト全体で共通のQSSを設定することもできる。<br> | |||
QSSの書式や構文は、CSSとほぼ同じである。<br> | |||
<br> | |||
以下の例は、Qtに付属しているサンプルを参考にしている。<br> | |||
(<Qtのインストールディレクトリ>/Examples/Qt-<バージョン名>/widgets/widgets/stylesheetディレクトリ)<br> | |||
まず、MainWindow.qssファイルを作成する。<br> | |||
<syntaxhighlight lang="css"> | |||
// MainWindow.qss | |||
// QPushButtonの設定例 | |||
QPushButton | |||
{ | |||
background-color: #000088; | |||
border-color: #000044; | |||
border-style: solid; | |||
border-radius: 5; | |||
} | |||
QPushButton:hover | |||
{ | |||
background-color: #880000; | |||
} | |||
QPushButton:pressed | |||
{ | |||
background-color: #008800; | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
次に、MainWindow.qssファイルをQApplicationクラスのsetStyleSheetメソッドに渡す。<br> | |||
QApplicationクラスのインスタンスはシングルトンとして生成されているため、そのインスタンスから実行する。<br> | |||
また、QSSファイルはリソースとして登録しておくとよい。<br> | |||
<br> | |||
以下の例では、main関数でQSSファイルを読み込み、設定している。<br> | |||
QSSには、他にも様々なクラスやセレクタが存在する。<br> | |||
<syntaxhighlight lang="c++"> | |||
#include "MainWindow.h" | |||
#include <QtCore> | |||
int main(int argc, char *argv[]) | |||
{ | |||
QApplication app(argc, argv); | |||
QFile file(":/qss/MainWindow.qss"); | |||
file.open( QFile::ReadOnly ); | |||
QString strStyles = QLatin1String(file.readAll()); | |||
app.setStyleSheet( strStyles ); | |||
MainWindow w; | |||
w.show(); | |||
return app.exec(); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== ウィンドウの背景を画像にする ==== | |||
<code>QStyle</code>クラスは、ウィンドウの外見を詳細に設定することができる。<br> | |||
<br> | |||
<code>QStyle</code>クラスを継承した派生クラスを作成して、必要な項目のうち、比較的簡単に設定できる項目である。<br> | |||
<code>QStyle</code>クラスを継承した派生クラスは数種類用意されており、OSにより使用できるものが決まっている。<br> | |||
<br> | |||
以下の例は、<code>QStyle</code>クラスを継承した派生クラスを作成している。<br> | |||
<br> | |||
設定後、<code>QMainWindow</code>クラスまたは<code>QDialog</code>クラスのコンストラクタにおいて、以下のように記述して適用する。<br> | |||
<syntaxhighlight lang="c++"> | |||
QApplication::setStyle(new MyStyle); // MyStyleクラスは、QStyleクラスの派生クラス | |||
</syntaxhighlight> | |||
<br> | |||
ウィンドウの背景を画像にするには、まず、<code>polish</code>メソッドをオーバーライドする。<br> | |||
次に、画像を設定するためのsetTextureメソッド(メソッド名は任意)を作成する。<br> | |||
<syntaxhighlight lang="c++"> | |||
#pragma once | |||
#include <QStyle> | |||
class MyStyle : public QStyle | |||
{ | |||
public: | |||
MyStyle(); | |||
~MyStyle(); | |||
void polish(QPalette &palette); | |||
private: | |||
static void setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap); | |||
}; | |||
</syntaxhighlight> | |||
<br> | |||
<code>polish</code>メソッドとsetTextureメソッドは、以下のように記述する。<br> | |||
背景画像は、型抜き画像としても使用することができる。したがって、背景用画像と型抜き用画像の2つを用意する必要はない。<br> | |||
<syntaxhighlight lang="c++"> | |||
void MyStyle::polish(QPalette &palette) | |||
{ | |||
QPixmap backgroundImage("window.png"); | |||
setTexture(palette, QPalette::Window, backgroundImage); | |||
} | |||
void MyStyle::setTexture(QPalette &palette, QPalette::ColorRole role, const QPixmap &pixmap) | |||
{ | |||
for(int i = 0; i < QPalette::NColorGroups; ++i) | |||
{ | |||
QColor color = palette.brush(QPalette::ColorGroup(i), role).color(); | |||
palette.setBrush(QPalette::ColorGroup(i), role, QBrush(color, pixmap)); | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== ボタンのスタイルの変更 ==== | |||
上記のセクションにも記述した<code>polish</code>メソッドを使用して、ボタンのスタイルを変更することができる。<br> | |||
<br> | |||
<code>QPalette</code>クラスのコンストラクタでは、ボタンの色を定義する。<br> | |||
ウィンドウおよびコントロールの設定の詳細は、[http://doc-snapshot.qt-project.org/4.8/qpalette.html Qtの公式WebサイトのQPalleteリファレンス]を参照すること。<br> | |||
<syntaxhighlight lang="c++"> | |||
void MyStyle::polish(QPalette &palette) | |||
{ | |||
QPixmap backgroundImage("window.png"); | |||
// 追加部分 : ボタンスタイルを変更 | |||
palette = QPalette(QColor(0, 0, 0, 50)); | |||
palette.setBrush(QPalette::ButtonText, Qt::cyan); | |||
setTexture(palette, QPalette::Window, backgroundImage); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
また、ボタンの背景を画像に変更するには、以下のように記述する。<br> | |||
<syntaxhighlight lang="c++"> | |||
void MyStyle::polish(QPalette &palette) | |||
{ | |||
QPixmap backgroundImage("window.png"); | |||
// 追加部分 : ボタンの背景を画像にする場合 | |||
QPixmap buttonImage("button.png"); | |||
// 追加部分 : ボタンを押下した時の背景 | |||
QPixmap midImage = buttonImage; | |||
setTexture(palette, QPalette::Button, buttonImage); | |||
setTexture(palette, QPalette::Mid, midImage); | |||
setTexture(palette, QPalette::Window, backgroundImage); | |||
} | |||
</syntaxhighlight> | |||
<br> | |||
==== ウインドウおよびウィジェットの形状を変更する ==== | |||
ウインドウおよびウィジェットの形状を変更するには、ウィジェットの形状をプログラムで全て記述する必要がある。<br> | |||
<br> | |||
例えば、ボタンの形状を変更する場合、外形を描画するだけではなく、<br> | |||
ボタンが立体的に見えるように陰影の描画、ボタン押下時の陰影の変化等も記述する必要がある。<br> | |||
(或いは、QSS + 背景画像で形状を変更できる可能性がある)<br> | |||
<br> | |||
ウインドウおよびウィジェットの形状を記述するには、<code>QStyle</code>クラスを継承した派生クラスを作成して、<br> | |||
<code>QStyle</code>クラスの<code>drawPrimitive</code>メソッドをオーバーライドする。<br> | |||
<br> | |||
以下の例では、ボタンの形状を変更している。<br> | |||
Qtに付属しているサンプルを参考にしている。<br> | |||
(<Qtのインストールディレクトリ>/Examples/Qt-<バージョン名>/widgets/widgets/styles/norwegianwoodstyle.cppファイル)<br> | |||
<syntaxhighlight lang="c++"> | |||
void MyStyle::drawPrimitive(PrimitiveElement element, const QStyleOption *option, QPainter *painter, const QWidget *widget) const | |||
{ | |||
switch(element) | |||
{ | |||
// ウィジェットのPrimitiveの種類を指定する(ウィジェットの種類ではない) | |||
case PE_PanelButtonCommand: | |||
int delta = (option->state & State_MouseOver) ? 64 : 0; | |||
QColor slightlyOpaqueBlack(0, 0, 0, 63); | |||
QColor semiTransparentWhite(255, 255, 255, 127 + delta); | |||
QColor semiTransparentBlack(0, 0, 0, 127 - delta); | |||
int x, y, width, height; | |||
option->rect.getRect(&x, &y, &width, &height); | |||
// 以下の3行のみ追記する | |||
// ボタンの形状を楕円にする | |||
QPainterPath path; | |||
path.addEllipse(option->rect); | |||
// これ以降の記述はコピーである | |||
// ボタンの押下時と非押下時の陰影等を記述する | |||
// 様々な形状に対応している | |||
int radius = qMin(width, height) / 2; | |||
QBrush brush; | |||
bool darker; | |||
const QStyleOptionButton *buttonOption = qstyleoption_cast<const QStyleOptionButton *>(option); | |||
if(buttonOption && (buttonOption->features & QStyleOptionButton::Flat)) | |||
{ | |||
brush = option->palette.background(); | |||
darker = (option->state & (State_Sunken | State_On)); | |||
} | |||
else | |||
{ | |||
if(option->state & (State_Sunken | State_On)) | |||
{ | |||
brush = option->palette.mid(); | |||
darker = !(option->state & State_Sunken); | |||
} | |||
else | |||
{ | |||
brush = option->palette.button(); | |||
darker = false; | |||
} | |||
} | |||
painter->save(); | |||
painter->setRenderHint(QPainter::Antialiasing, true); | |||
painter->fillPath(path, brush); | |||
if(darker) | |||
{ | |||
painter->fillPath(path, slightlyOpaqueBlack); | |||
} | |||
int penWidth; | |||
if(radius < 10) | |||
penWidth = 3; | |||
else if (radius < 20) | |||
penWidth = 5; | |||
else | |||
penWidth = 7; | |||
QPen topPen(semiTransparentWhite, penWidth); | |||
QPen bottomPen(semiTransparentBlack, penWidth); | |||
if(option->state & (State_Sunken | State_On)) | |||
{ | |||
qSwap(topPen, bottomPen); | |||
} | |||
int x1 = x; | |||
int x2 = x + radius; | |||
int x3 = x + width - radius; | |||
int x4 = x + width; | |||
if(option->direction == Qt::RightToLeft) | |||
{ | |||
qSwap(x1, x4); | |||
qSwap(x2, x3); | |||
} | |||
QPolygon topHalf; | |||
topHalf << QPoint(x1, y) << QPoint(x4, y) << QPoint(x3, y + radius) << QPoint(x2, y + height - radius) << QPoint(x1, y + height); | |||
painter->setClipPath(path); | |||
painter->setClipRegion(topHalf, Qt::IntersectClip); | |||
painter->setPen(topPen); | |||
painter->drawPath(path); | |||
QPolygon bottomHalf = topHalf; | |||
bottomHalf[0] = QPoint(x4, y + height); | |||
painter->setClipPath(path); | |||
painter->setClipRegion(bottomHalf, Qt::IntersectClip); | |||
painter->setPen(bottomPen); | |||
painter->drawPath(path); | |||
painter->setPen(option->palette.foreground().color()); | |||
painter->setClipping(false); | |||
painter->drawPath(path); | |||
painter->restore(); | |||
break; | |||
default: | |||
// ボタン以外はMotifStyleの形状を採用 | |||
QMotifStyle::drawPrimitive(element, option, painter, widget); | |||
break; | |||
} | |||
} | |||
</syntaxhighlight> | |||
<br><br> | |||
{{#seo: | |||
|title={{PAGENAME}} : Exploring Electronics and SUSE Linux | MochiuWiki | |||
|keywords=MochiuWiki,Mochiu,Wiki,Mochiu Wiki,Electric Circuit,Electric,pcb,Mathematics,AVR,TI,STMicro,AVR,ATmega,MSP430,STM,Arduino,Xilinx,FPGA,Verilog,HDL,PinePhone,Pine Phone,Raspberry,Raspberry Pi,C,C++,C#,Qt,Qml,MFC,Shell,Bash,Zsh,Fish,SUSE,SLE,Suse Enterprise,Suse Linux,openSUSE,open SUSE,Leap,Linux,uCLnux,Podman,電気回路,電子回路,基板,プリント基板 | |||
|description={{PAGENAME}} - 電子回路とSUSE Linuxに関する情報 | This page is {{PAGENAME}} in our wiki about electronic circuits and SUSE Linux | |||
|image=/resources/assets/MochiuLogo_Single_Blue.png | |||
}} | |||
__FORCETOC__ | __FORCETOC__ | ||
[[カテゴリ:Qt]] | [[カテゴリ:Qt]] | ||