Qtインターフェースのレイアウト管理について詳しく解説

この記事では、少し複雑な例を使用して、インターフェイス設計時のレイアウト管理やプログラム内のインターフェイス コンポーネントへのアクセス方法など、GUI 設計の一般的な機能を説明します。

サンプルプログラム関数

ウィジェット アプリケーション プロジェクト samp2_2 を作成し、フォームの作成時に基本クラス QDialog を選択し、生成されたクラスに QWDialog という名前を付けて、フォームの生成を選択します。

新しく作成されたプロジェクト samp2_2 には、インターフェース ファイル qwdialog.ui、ヘッダー ファイル qwdialog.h、およびソース プログラム ファイル qwdialog.cpp があります。さらに、プロジェクト ファイル samp2_2.pro とメイン プログラム ファイル main.cpp があります。

qwdialog.ui インターフェイス ファイルの設計インターフェイスを図 1 に示します。このプログラムの主な機能は、中央のテキスト ボックスのテキスト フォント スタイルと色を設定することです。

この記事の利点は、 Qt 開発学習教材パッケージ、技術ビデオ (C++ 言語基礎、C++ デザイン パターン、Q​​t プログラミング入門、QT シグナルとスロット メカニズム、QT インターフェイス開発イメージ描画、QT ネットワーク、QT を含む) を無料で受け取ることです。データベースプログラミング、QTプロジェクト実戦、QSS、OpenCV、Quickモジュール、面接での質問など) ↓↓↓↓下記参照↓↓料金受け取りは記事下部をクリック↓↓

 

図 1 サンプル プログラム samp2_2 の設計時インターフェイス

インターフェイスを設計する際、各ボタン、入力を読み取る必要があるエディットボックス、結果を表示する必要があるラベルなど、アクセスする必要があるコンポーネントの objectName を区別できるように変更します。プログラム内で。プログラムへのアクセスを必要としないコンポーネントの場合、インターフェイス上でコンポーネントをグループ化するために GroupBox、Frame、layout などの objectName を変更する必要はなく、UI デザイナーが自動的に名前を付けます。

表 2 qwdialog.ui の各コンポーネントの関連設定
オブジェクト名 クラス名 プロパティ設定 述べる
txt編集  Qプレーンテキスト編集 Text="Hello, World
これは私のデモです。"
Font.PointSize=20
テキストコンテンツを表示するために使用され、編集可能
chkBoxUnder  Qチェックボックス  テキスト="下線" フォントに下線を設定する
chkBox斜体  Qチェックボックス  テキスト = "斜体" フォントを斜体に設定
チェックボックス太字  Qチェックボックス  テキスト=「太字」 フォントを太字に設定
rBtnブラック  Qラジオボタン  テキスト=「黒」 文字色は黒です
rBtn赤  Qラジオボタン  テキスト=「赤」 文字の色は赤です
rBtnBlue  Qラジオボタン  テキスト=「青」 文字色は青です
btnOK  Qプッシュボタン  テキスト = "OK" OKを返してウィンドウを閉じます
btnキャンセル  Qプッシュボタン  テキスト=「キャンセル」  戻ってキャンセルし、ウィンドウを閉じます
btn閉じる  Qプッシュボタン  テキスト=「終了」 プログラムを終了する
QWDialog  QWDialog  windowTitle="デザイナーによるダイアログ" インターフェイス ウィンドウのクラス名は QWDialog です。objectName は変更しないでください。


インターフェース部品のプロパティ設定では、以下の点に注意する必要があります。

  1. objectName は、フォーム上に作成されたコンポーネントのインスタンス名です。インターフェイス上の各コンポーネントには、一意の objectName が必要です。プログラム内でインターフェイス コンポーネントにアクセスするときは、objectName を通じてアクセスされ、自動生成されたスロット関数名にも名前が付けられます。オブジェクト名。したがって、コンポーネントのobjectNameはプログラム設計前に設定する必要があり、通常は設定後に変更する必要はありません。プログラムの設計後に objectName が変更された場合は、それに応じて関連するコードも変更する必要があります。
  2. フォームの objectName は、フォームのクラス名です。UI デザイナーでフォームの objectName を変更しないでください。フォームのインスタンス名は、フォームを使用するコードで定義する必要があります。

インターフェースコンポーネントのレイアウト

Qtのインターフェースデザインにはレイアウト機能が使われています。いわゆるレイアウトとは、インターフェイス上のコンポーネントの配置を指し、コンポーネントを規則的に配置し、フォームのサイズの変化に応じてサイズや相対位置を自動的に調整することができます。レイアウト管理は GUI 設計において必須のスキルであり、図 1 に示すインターフェイス設計を実現する方法をステップごとに説明します。

インターフェースコンポーネントの階層関係

インターフェイス上でさまざまなコンポーネントの配置をより美しく設計するために、QgoupBox、QtabWidget、QFrame などのいくつかのコンテナ クラスがよく使用されます。

たとえば、GroupBox コンポーネントに 3 つの CheckBox コンポーネントを配置すると、GroupBox コンポーネントはこれら 3 つの CheckBox のコンテナとなり、この GroupBox を移動すると 3 つの CheckBox が同時に移動します。

 

図 3 インターフェースコンポーネントの配置と階層関係

図 3 は、図 1 のインターフェイス設計の初期段階を示しています。フォーム上に 2 つの GroupBox コンポーネント、groupBox1 に 3 つの CheckBox コンポーネント、groupBox2 に 3 つの RadioButton コンポーネントが配置されます。図 3 の右側にあるオブジェクト インスペクターは、インターフェイス上のコンポーネント間の階層関係を示しています。

レイアウト管理

Qt はインターフェイス設計のための豊富なレイアウト管理機能を提供します。UI デザイナーには、コンポーネント パネルにレイアウトとスペーサーという 2 つのコンポーネント パネルがあり、フォームの上のツールバーにはレイアウト管理用のボタンがあります (図 4 を参照)。 。

 

図 4 レイアウトビジュアルデザイン用のコンポーネントパレットとツールバー

[レイアウト] および [スペーサー] コンポーネント パネルのレイアウト コンポーネントの機能を表 5 に示します。

表 5 コンポーネント パネルのレイアウトに使用されるコンポーネント
レイアウトコンポーネント 関数
縦型レイアウト 垂直レイアウト、コンポーネントは自動的に垂直方向に配置されます。
横型レイアウト 横型レイアウト、コンポーネントは自動的に横方向に配置されます。
グリッドレイアウト グリッド レイアウト、グリッド レイアウトのサイズが変更されると、各グリッドのサイズも変更されます
フォームのレイアウト フォーム レイアウト。グリッド レイアウトに似ていますが、グリッドの右端の列のみサイズが変更されます。
水平スペーサー 水平方向の分離スペース
垂直スペーサー 縦に区切るスペース

コンポーネント パネルのレイアウト コンポーネントを使用してレイアウトを設計する場合は、まずレイアウト コンポーネントをフォーム上にドラッグ アンド ドロップします。たとえば、図 4 の 3 つのボタンのレイアウトを設計する場合、まずフォーム上に水平レイアウトを配置し、レイアウトコンポーネントが赤色で表示されます。 フレームが表示されます。次に、3 つのプッシュ ボタンと 2 つの水平スペーサーをレイアウト コンポーネントにドラッグ アンド ドロップして、図 1 の 3 つのボタンの水平レイアウト効果を取得します。

デザインフォームの上部にはツールバーがあり、デザイナーがさまざまな状態を入力したり、レイアウト設計を実行したりするために使用されます。ツールバーのボタンの機能は表 6 に示されています。

表 6 UI デザイナー ツールバーの各ボタンの機能
ボタンとショートカット 関数
ウィジェットの編集 (F3) インターフェイス デザインは、通常のデザイン状態である編集状態に入ります。
信号/スロットの編集(F4)  信号とスロットの視覚的な設計状態を入力します。
仲間の編集 パートナーシップ編集状態に入り、パートナーシップとなるラベルとコンポーネントを設定できます。
タブオーダーの編集 タブ オーダー編集状態に入ります。タブ オーダーとは、キーボードの Tab キーが押されたときに入力フォーカスがインターフェイスのコンポーネント間を移動する順序です。
水平方向にレイアウト (Ctrl+H) 選択したコンポーネントをフォーム上に水平に配置します
縦方向にレイアウト (Ctrl+L)  選択したコンポーネントをフォーム上に垂直に配置します
スプリッターで水平にレイアウト フォーム上で選択したコンポーネントのレイアウトを分割バーを使用して水平方向に分割します。
スプリッターで垂直にレイアウト 分割バーを使用して、フォーム上で選択したコンポーネントのレイアウトを垂直に分割します。
フォームレイアウトにレイアウトする 選択したコンポーネントをフォームに従ってフォーム上に配置します。
グリッドにレイアウトする 選択したコンポーネントをフォーム上にグリッド レイアウトします。
ブレークレイアウト フォーム上で選択したコンポーネントのレイアウトを解放します。つまり、既存のレイアウトを分割します。
サイズ調整(Ctrl+J) 選択したコンポーネントのサイズを自動的に変更する

使用工具栏上的布局控制按钮时,只需在窗体上选中需要设计布局的组件,然后点击某个布局按钮即可。在窗体上选择组件时同时按住 Ctrl 键,可以实现组件多选,选择某个容器类组件,相当于选择了其内部的所有组件。

例如,在图 3 的界面中,选中 groupBox1,然后单击“Lay Out Horizontally”工具栏按钮,就可以对 groupBox1 内的 3 个 CheckBox 水平布局。

在图 4 的界面上,使 groupBox1 里的 3 个 CheckBox 水平布局,groupBox2 里的 3 个 RadioButton 水平布局,下方 3个按钮水平布局。在窗体上又放置了一个 PlainTextEdit 组件。现在,改变 groupBox1、groupBox2 或按钮的水平布局的大小,其内部组件都会自动改变大小。但是当改变窗体大小时,界面上的各组件却并不会自动改变大小。

随后还需为窗体指定一个总的布局。选中窗体(即不要选择任何组件),单击工具栏上的“Lay Out Vertically”按钮,使 4 个组件垂直分布。这样布局后,当窗体大小改变时,各个组件都会自动改变大小。

在 UI 设计器里可视化设计布局时,要善于利用水平和垂直空格组件,善于设置组件的最大、最小宽度和高度来实现某些需要的布局效果。

伙伴关系与 Tab 顺序

在 UI 设计工具栏上单击“Edit Buddies”按钮可以进入伙伴关系编辑状态,如设计一个窗体时,进入伙伴编辑状态之后的界面如图 7 所示。

 

图 7 编辑伙伴关系


伙伴关系(Buddy)是指界面上一个 Label 和一个组件相关联,如图 7 中的伙伴关系编辑状态,单击一个 Label,按住鼠标左键,然后拖向一个组件,就建立了 Label 和组件之间的伙伴关系。

伙伴关系是为了在程序运行时,在窗体上用快捷键快速将输入焦点切换到某个组件上。例如,在图 7 的界面上,设定“姓名”标签的 Text 属性为“姓名(&N)”,其中符号“&”用来指定快捷字符,界面上并不显示“&”,这里指定快捷字母为 N。那么程序运行时,用户按下Alt+N,输入焦点就会快速切换到“姓名”关联的输入框内。

 

图 8 Tab 顺序编辑状态


在 UI 设计器工具栏上单击“Edit Tab Order”按钮进入Tab 顺序编辑状态(如图 8 所示)。Tab 顺序是指在程序运行时,按下键盘上的 Tab 键时输入焦点的移动顺序。一个好的用户界面,在按 Tab 键时,焦点应该以合理的顺序在界面上移动,而不是随意地移动。

进入 Tab 顺序编辑状态后,在界面上会显示具有 Tab 顺序组件的编号,依次按希望的顺序单击组件,就可以重排 Tab 顺序了。没有输入焦点的组件是没有 Tab 顺序的,如 Label 组件。

项目功能实现

下面开始设计程序功能。对于该程序,希望它的功能如下:

  1. 单击 UnderLine、Italic、Bold 3 个 CheckBox 时,根据其状态,设置 PlainTextEdit 里的文字的字体样式;
  2. Black、Red、Blue 3 个 RadioButton 是互斥选择的,单击某个 RadioButton 时,设置文字的颜色;
  3. 单击“确定”“取消”或“退出”按钮时,关闭窗口,退出程序。

字体样式设置

窗体在设计模式下,选中 chkBoxUnder 组件,单击右键调出其快捷菜单。在快捷菜单中单击菜单项“Go to slot…”(中文状态为“转到槽”),出现如图 9 所示的对话框。

 图 9 QcheckBox的Go to slot对话框


该对话框列出了 QCheckBox 类的所有信号,第一个是 clicked(),第二个是带一个布尔类型参数的 clicked(bool)。

信号 clicked(bool) 会将 CheckBox 组件当前的选择状态作为一个参数传递,在响应代码里可以直接利用这个传递的参数。而如果用信号 clicked(),则需要在代码里读取 CheckBox 组件的选中状态。为了简化代码,选择 clicked(bool) 信号。

选择 clicked(bool),然后单击“OK”按钮,在 QWDialog 的类定义中,会在 private slots 部分自动增加一个槽函数声明,函数名是根据发射对象及其信号名称自动命名的。

void on_chkBoxUnder_clicked(bool checked);

同时,在 qwdialog.cpp 文件中自动添加了函数 on_chkBoxUnder_clicked(bool) 的框架,在此函数中添加如下的代码,实现文本框字体下划线的控制。

void QWDialog::on_chkBoxUnder_clicked(bool checked)
{
    QFont font=ui->txtEdit->font();
    font.setUnderline(checked);
    ui->txtEdit->setFont(font);
}

以同样的方法为 Italic 和 Bold 两个 CheckBox设计槽函数,编译后运行,发现已经实现了修改字体的下划线、斜体、粗体属性的功能,说明信号与槽函数已经关联了。

但是,查看 QWDialog 的构造函数,构造函数只有简单的一条语句。

QWDialog::QWDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QWDialog)
{
    ui->setupUi(this);
}

这里没有发现用 connect() 函数进行几个 CheckBox 的信号与槽函数关联的操作。这些功能是如何实现的呢?

查看编译生成的 ui_qwdialog.h 文件。构造函数里调用的 setupUi() 是在 ui_qwdialog.h 文件里实现的。查看 setupUi() 函数的内容,也没有发现用 connect() 函数进行几个 CheckBox 的信号与槽关联的操作,只是在 setupUI()里发现了如下的一条语句:

QMetaObject::connectSlotsByName(QWDialog);

秘密就在于这条语句。connectSlotsByName(QWDialog) 函数将搜索 QWDialog 界面上的所有组件,将信号与槽函数匹配的信号和槽关联起来,它假设槽函数的名称是:

void on_<object name>_<signal name>(<signal parameters>);

例如,通过 UI 设计器的操作,为 chkBoxUnder 自动生成的槽函数是:

void on_chkBoxUnder_clicked(bool checked);

它就正好是 chkBoxUnder 的信号 clicked(bool) 的槽函数。那么,connectSlotsByName() 就会将此信号和槽函数关联起来,如同执行了下面的这样一条语句:

connect(chkBoxUnder, SIGNAL(clicked (bool)),
this, SLOT (on_chkBoxUnder_clicked (bool));

这就是用 UI 设计器可视化设计某个组件的信号响应槽函数,而不用手工去将其关联起来的原因,都是在界面类的构造函数里调用 setupUi() 自动完成了关联。

字体颜色设置

设置字体的 3 个 RadioButton 是互斥性选择的,即一次只有一个 RadioButton 被选中,虽然也可以采用可视化设计的方式设计其 clicked() 信号的槽函数,但是这样就需要生成 3 个槽函数。这里可以简化设计,即设计一个槽函数,将 3 个 RadioButton 的 clicked() 信号关联到这一个槽函数。

为此,在 QWDialog 类的 private slots 部分增加一个槽函数定义如下:

void setTextFontColor();

提示 将鼠标光标移动到这个函数的函数名上面,单击右键,在弹出的快捷菜单中选择“Refactor”→“Add Definition in qwdialog.cpp”,就可以在 qwdialog.cpp 文件中自动为函数 setTextFontColor() 生成一个函数框架。

在 qwdialog.cpp 文件中,为 setTextFontColor() 编写实现代码如下:

void QWDialog::setTextFontColor()
{
    QPalette plet=ui->txtEdit->palette();
    if (ui->rBtnBlue->isChecked())
        plet.setColor(QPalette::Text,Qt::blue);
    else if (ui->rBtnRed->isChecked())
       plet.setColor(QPalette::Text,Qt::red);
    else if (ui->rBtnBlack->isChecked())
        plet.setColor(QPalette::Text,Qt::black);
    else
       plet.setColor(QPalette::Text,Qt::black);
    ui->txtEdit->setPalette(plet);
}

由于这个槽函数是自定义的,所以不会自动与 RadioButton 的 clicked() 事件关联,此时编译后运行程序不会实现改变字体颜色的功能。需要在 QWDialog 的构造函数中手工进行关联,代码如下:

QWDialog::QWDialog(QWidget *parent) : QDialog(parent), ui(new Ui::QWDialog)
{
    ui->setupUi(this);
    connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
    connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));
}

在构造函数中将 3 个 RadioButton 的 clicked() 信号与同一个槽函数 setTextFontColor() 相关联。再编译后运行,就可以更改文字的颜色了。

三个按钮的功能设计

界面上还有“确定”“取消”“退出”3 个按钮,这是在对话框中常见的按钮。“确定”表示确认选择并关闭对话框,“取消”表示取消选择并关闭对话框,“退出”则直接关闭对话框。

QWDialog 是从 QDialog 继承而来的,QDialog 提供了 accept()、reject()、close() 等槽函数来表示这三种状态,只需将按钮的 clicked() 信号与相应槽函数关联即可。

下面采用可视化的方式,将按钮的 clicked() 信号与这些槽函数关联起来。在 UI 设计器里,单击上方工具栏里的“Edit Signals/Slots”按钮,窗体进入信号与槽函数编辑状态,如图 10 所示。

 

图 10 窗体进入Signals/Slot编辑状态


将鼠标移动到“确定”按钮上方,再按下鼠标左键,移动到窗体的空白区域释放左键,这时出现如图 11 所示的关联设置对话框。

 

图 11 信号与槽关联编辑对话框


在图 11 中,左侧的列表框里显示了 btnOK 的信号,选择 clicked(),右边的列表框里显示了 QWDialog 的槽函数,选择 accept(),单击“OK”按钮。

同样的方法可以将 btnCancel 的 clicked() 信号与 QWDialog 的 reject() 槽函数关联,将 btnClose 的 clicked() 信号与 QWDialog 的 close() 槽函数关联。

注意,在图 11 的右侧列表框中没有 close() 槽函数,需要勾选下方的“Show signals and slots inherited from QWidget”才会出现 close() 函数。

设置完 3 个按钮的信号与槽关联之后,在窗体下方的 Signals 和 Slots 编辑器里也显示了这 3 个关联。实际上,可以直接在 Signals 和 Slots 编辑器进行关联设置。现在编译并运行程序,单击这 3 个按钮都会关闭程序。

那么,这 3 个按钮的信号与槽函数的关联是在哪里实现的呢?答案在 setupUi() 函数里,在 setupUi() 函数里自动增加了以下 3 行代码:

Object::connect(btnOK, SIGNAL(clicked()), QWDialog, SLOT(accept()));
QObject::connect(btnCancel, SIGNAL(clicked()), QWDialog, SLOT(reject()));
QObject::connect(btnClose, SIGNAL(clicked()), QWDialog, SLOT(close()));

这个实例程序的功能全部完成了。采用 UI 设计器设计了窗体界面,采用可视化和程序化的方式设计槽函数,设计信号与槽函数之间的关联。

从以上的设计过程可以看到,Qt Creator 和 UI 设计器为设计应用程序提供了强大的可视化设计功能。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,C++设计模式,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

おすすめ

転載: blog.csdn.net/m0_73443478/article/details/131404541