02-0_Qt 5.9 C++ 開発ガイド_GUI アプリケーション設計の基礎 (UI 設計で使用するファイルの作成と全体の動作メカニズム、UI 設計フレームワークの例、ビジュアル UI 設計、コード化された UI 設計、ハイブリッド UI 設計 (QMainwindow))

この記事では、Qt Creator を使用して UI デザインを作成するために使用するファイルと全体的な動作メカニズムを紹介します。例外として、ビジュアル UI デザイン (QDialog)、コード化された UI デザイン (QDialog)、およびハイブリッド UI デザイン (QMainwindow) について例を示して詳しく紹介します。

GUI アプリケーション設計の基礎

1.UIファイルの設計と運用の仕組み

このセクションでは主に、Widget Application プロジェクトに含まれるファイルとその詳細な内容について説明し、Qt で作成された GUI アプリケーション プログラム内の各ファイルの機能を分析し、視覚的に設計された UI ファイルがどのように C++ クラス定義に変換され、インターフェースが自動作成されるかを分析します。これらは、QtCreator を使用してユーザー インターフェイスを視覚的にデザインし、さまざまな部分を連携させるための基本原則です。

主に次のファイルの内容が含まれます。

  • プロジェクト構成ファイル samp2_1.pro (プロジェクトの設定を保存するファイル)

  • メイン プログラム エントリ ファイル main.cpp は、main() 関数を実装するプログラム ファイルです。

  • フォーム インターフェイス ファイル widget.ui。フォーム上の要素とそのレイアウトを XML 形式で保存するファイルです。ウィンドウ上のすべてのコンポーネントのプロパティ設定レイアウト、信号とスロット機能の関連付けなどを定義します。UIデザイナーが視覚的にデザインしたインターフェースはQtによって自動的に解析され、XMLファイルの形式で保存されます。インターフェイスを設計するときは、widget.ui に関係なく、UI デザイナーでビジュアル デザインを実行するだけで済みます。

  • widget.h は設計されたウィンドウ クラスのヘッダー ファイルであり、widget.cpp は widget.h で定義されたクラスの実装ファイルです。C++ では、フォームまたはインターフェイス コンポーネントはすべてクラスによってカプセル化され、クラスには通常、ヘッダー ファイル (.h ファイル) とソース プログラム ファイル (.cpp ファイル) が含まれます。

各ファイルのコードの意味の詳細は、必要に応じて「Qt5.9 C++ 開発ガイド」で確認できますので、確認しておくと後の理解に役立ちます。

2.ビジュアルUIデザイン

以下では例を使用して、視覚化による UI の設計方法を紹介します。

2.1 サンプルプログラムの機能

プログラムのインターフェースは次のとおりです

ここに画像の説明を挿入

機能を実現します。

このプログラムの主な機能は、中央のテキスト ボックスのテキスト フォント スタイルと色を設定することです。

「Qt5.9 C++ 開発ガイド」では、後続のプログラミングのための各コンポーネントの名前とプロパティの設定について説明します。説明書によると、初期インターフェイスは次のようになります。

ここに画像の説明を挿入

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

Qtのインターフェースデザインにはレイアウト機能が使われています。いわゆるレイアウトとは、インターフェイス上のコンポーネントの配置を指し、コンポーネントを規則的に配置し、フォームのサイズの変化に応じてサイズや相対位置を自動的に調整することができます。以下、実装プロセスをステップごとに説明します。

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

インターフェイス上でのさまざまなコンポーネントの配置をより美しく設計するために、 QgoupBox、などのいくつかのコンテナ クラスがQtabWidgetよく使用されますQFrameたとえば、GroupBox コンポーネントに 3 つの CheckBox コンポーネントを配置すると、GroupBox コンポーネントはこれら 3 つの CheckBox のコンテナとなり、この GroupBox を移動すると 3 つの CheckBox が同時に移動します。

フォームに 2 つの GroupBox コンポーネントを配置し、groupBox1 に 3 つの CheckBox コンポーネントを配置し、groupBox2 に 3 つの RadioButton コンポーネントを配置すると、その効果が次の図に示されます。

ここに画像の説明を挿入

2.2.2 レイアウト管理

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

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

ここに画像の説明を挿入

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

ここに画像の説明を挿入

ツールバーのレイアウト コントロール ボタンを使用する場合は、フォーム上のレイアウトを設計する必要があるコンポーネントを選択し、特定のレイアウト ボタンをクリックするだけです。Ctrl キーを押したままフォーム上のコンポーネントを選択すると、複数のコンポーネントを選択できます。コンテナ クラス コンポーネントを選択することは、そのコンポーネント内のすべてのコンポーネントを選択することと同じです。

たとえば、上記のインターフェイスでは、groupBox を選択し、[水平にレイアウト] ツールバー ボタンをクリックして、groupBoxl 内の 3 つのチェックボックスを水平にレイアウトします。

インターフェース上で、groupBox1の3つのCheckBoxを横レイアウト、groupBox2の3つのRadioButtonを横レイアウト、その下の3つのボタンを横レイアウトにします。別の PlainTextEdit コンポーネントがフォーム上に配置されます。ここで、groupBox1、groupBox2、またはボタンの水平レイアウトのサイズを変更すると、その内部コンポーネントのサイズが自動的に変更されます。ただし、フォームのサイズを変更しても、インターフェイス上のコンポーネントのサイズは自動的に変更されません。

(3) 次に、フォームの一般的なレイアウトを指定する必要があります。フォームを選択し(コンポーネントを選択しないで)、ツールバーの「垂直レイアウト」ボタンをクリックして、4 つのコンポーネントを垂直方向に配置します。このレイアウト以降、フォームのサイズが変更されると、各コンポーネントのサイズも自動的に変更されます。

最終的なレイアウト効果を次の図に示します。
ここに画像の説明を挿入

UI デザイナーでレイアウトを視覚的にデザインするときは、水平および垂直スペース コンポーネントの使用に熟達し、特定の望ましいレイアウト効果を達成するためにコンポーネントの最大および最小の幅と高さを設定することに熟達している必要があります。

2.2.3 パートナーシップとタブオーダー

伙伴关系プログラム実行中にショートカットキーで入力フォーカスをフォーム上の特定のコンポーネントに素早く切り替えることであり、プログラムTab 顺序実行中にキーボードのTabキーを押したときの入力フォーカスの移動シーケンスを指します。詳細は『Qt5.9 C++開発ガイド』の該当内容を参照してください。

2.3 シグナルとスロットの簡単な紹介

2.3.1 信号スロットの基本概念

シグナル (Signal) は、特定の状況下で発行されるイベントです。たとえば、PushButton の最も一般的なシグナルは、マウスがクリックされたときに発行される clicked() シグナルです。ComboBox の最も一般的なシグナルは、選択されたリスト項目が変更されたときに発行される CurrentIndexChanged() シグナルです。GUI プログラムの設計の主な内容は、インターフェース上の各コンポーネントの信号に応答することであり、どのような状況でどの信号が発せられるかを知り、それらの信号に適切に応答して処理することだけが必要です。
スロットは信号に応答する関数です。スロットは一般的な C++ 関数と同じ関数であり、クラス (パブリック、プライベート、またはプロテクト) の任意の部分で定義でき、任意のパラメーターを持つことができ、直接呼び出すこともできます。スロット関数と一般関数の違いは、スロット関数は信号に関連付けることができ、信号が送信されると、関連付けられたスロット関数が自動的に実行されることです。

2.3.2 信号スロットの基本フォーマット

シグナルとスロット間の関連付けは QObject::connect() 関数で実装され、その基本形式は次のとおりです。

QObject::connect(sender,SIGNAL(signal()),receiver,SLOT(slot()));

connect() は OObiect クラスの静的関数であり、OObiect はすべての Ot クラスの基本クラスです。実際に呼び出すときに前の修飾子は無視できるため、次のように直接記述できます。
connect(sender,SIGNAL(signal()), receiver, SLOT(slot()));

  • sender はシグナルを発行するオブジェクトの名前で、signal() はシグナル名です。シグナルは括弧で囲む必要がある特別な関数とみなすことができ、パラメーターがある場合はパラメーターを指定する必要があります。receiver はシグナルを受信するオブジェクトの名前、slot() はスロット関数の名前です。スロット関数は括弧で囲む必要があり、パラメーターがある場合はパラメーターを指定する必要があります。

  • SIGNAL と SLOT は Qt のマクロで、シグナルとスロットを指定し、それらのパラメーターを対応する文字列に変換するために使用されます。たとえば、前の記事の ui widget.h ファイルでは、setupUi() 関数に次のステートメントがあります。
    QObject;:connect(btnClose,SIGNAL(clicked()),Widget,SLOT(close()));

    その機能は、btnClose ボタンの clicked() 信号をフォーム (ウィジェット) のスロット関数 close() に関連付けることで、btnClose ボタン (つまり、インターフェース上の「閉じる」ボタン) がクリックされると、ウィジェットの close (スロット関数) が実行されます。

2.3.3 信号スロット使用上の注意事項

  • 信号は複数のスロットに接続できます。

  • 複数の信号を同じスロットに接続できます。

  • 信号は別の信号に接続できます。

  • 厳密に言うと、信号とスロットのパラメータの数と種類は一致している必要があり、少なくとも信号のパラメータがスロットのパラメータより小さくてはなりません。不一致がある場合、コンパイル エラーまたは実行時エラーが発生します。;

  • シグナルとスロットを使用するクラスでは、マクロ Q OBJECT をクラス定義に追加する必要があります。

  • シグナルが発行されると、通常は、通常の関数呼び出しと同様に、関連するスロットが即座に実行されます。信号に関連付けられたすべてのスロット関数が実行された後にのみ、放出信号の背後にあるコードが実行されます。

2.4 スロット関数のプロトタイプとフレームワークを視覚的に生成する

2.4.1 機能要件

  • UnderLine、Italic、Bold 3 チェックボックスをクリックすると、その状態に応じて PlainTextEdit のテキストのフォント スタイルを設定します
  • 黒、赤、青の 3 つのラジオボタンは相互に排他的な選択です。ラジオボタンをクリックすると、テキストの色が設定されます。
  • [OK]、[キャンセル]、または [終了] ボタンをクリックすると、ウィンドウを閉じてプログラムを終了します。

2.4.2 フォントスタイルの設定

2.4.2.1 機能実現

checkBoxUnder コンポーネントを選択し、右クリックしてショートカット メニューを表示します。ショートカット メニューのメニュー項目「スロットに移動」をクリックすると、次のインターフェースが表示されます。信号
ここに画像の説明を挿入
clicked(bool) は、CheckBox コンポーネントの現在の選択ステータスをパラメーターとして渡します。この渡されたパラメーターは、応答コードで直接使用できます。また、clicked0 信号を使用する場合は、コード内で CheckBox コンポーネントの選択状態を読み取る必要があります。コードを簡素化するには、clicked(bool) 信号を選択します。「OK」をクリックすると、Dialog.h にスロット関数の宣言が追加されます。

 private slots:
    void on_checkBoxUnder_clicked(bool checked);

フレームワークは .cpp に自動的に追加されvoid Dialog::on_checkBoxUnder_clicked(bool checked)、対応するコードをその中に追加できます。

斜体チェックボックスと太字チェックボックスのスロット関数も同様に設計し、コンパイルして実行すると、目的の機能が実現されていることがわかります。

ここに画像の説明を挿入

2.4.2.2 ビジュアル UI デザインにおける信号スロット接続の原理

上記の結果は、信号がスロットに関連付けられていることを示していますが、コンストラクターには次の文しかありません。

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

コンパイルされた ui_qwdialog.h ファイルを確認します。コンストラクターで呼び出される setupUi() は ui_qwdialog.h ファイルに実装されており、setupUi() には信号スロットに関連する操作はありませんが、次のステートメントがあります。

QMetaObject::connectSlotsByName(Dialog);

秘密はこの文にあり、QMetaObject::connectSlotsByName(Dialog);ダイアログ インターフェイス上のすべてのコンポーネントを検索し、信号と一致するスロットをスロット関数に関連付けます。スロット関数の名前は次のとおりであると想定しています。

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

  • 例えば

    UI デザイナーの操作により、checkBoxUnder に対して自動的に生成されるスロット関数は次のとおりです。on_checkBoxUnder_clicked(bool checked)

    これはたまたま checkBoxUnder の clicked(bool) 信号のスロット関数であるだけです。次に、connectSlotsByName0) は、次のステートメントを実行するかのように、この信号をスロット関数に関連付けます。

    connect(checkBoxUnder,SIGNAL(clicked(bool)),this,SLOT(on_checkBoxUnder_clicked(bool)));

このため、UI デザイナーは、特定のコンポーネントの信号応答スロット関数を手動で関連付けるのではなく、視覚的に設計するために使用され、関連付けはインターフェイス クラスのコンストラクターで setupUi() を呼び出すことで自動的に完了します。

2.4.3 文字色の設定

(1) 3 つの RadioButton Black、Red、Blue は相互に排他的です。RadioButton がクリックされると、テキストの色が設定されます。 clicked() 信号のスロット関数は視覚的に設計することもできますが、この方法では 3 つのスロット関数が生成されます。ここでは、設計を簡素化するために、3 つの RadioButton の clicked() 信号がこのスロット関数に接続されています。

.h を追加します:

private slots:    
    void setTextFontColor();

(2) マウスをスロット関数の上に置き、「Alt+Enter」を押すと、対応する実装とコードを .cpp に追加できます。

(3) このスロット関数は自己定義であるため、RadioButton の clicked() イベントに自動的に関連付けられることはなく、このときコンパイル後にプログラムを実行しても文字色の変更機能は実現されません。コンストラクターで手動で関連付ける必要があります。コードは次のとおりです。

    connect(ui->rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));//信号与槽的关联
    connect(ui->rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));//信号与槽的关联
    connect(ui->rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));//信号与槽的关联

コンパイルして実行すると、結果は次のようになります。

ここに画像の説明を挿入

2.4.4 3 つのボタンの機能設計

2.4.4.1 機能の実現

インターフェイスには、ダイアログ ボックスでよく使用される「OK」、「キャンセル」、「終了」の 3 つのボタンもあります。「OK」は選択を確定してダイアログ・ボックスを閉じることを意味し、「キャンセル」は選択をキャンセルしてダイアログ・ボックスを閉じることを意味し、「終了」はダイアログ・ボックスを直接閉じることを意味します。

Dialog は QDialog から継承されています。QDialog は、これら 3 つの状態を表すために、accept0、reject0)、close0 などのスロット関数を提供します。ボタンの clicked0 信号を対応するスロット関数に関連付ける必要があるだけです。

以下では、視覚的な方法を使用して、ボタンの clicked0) 信号をこれらのスロット関数に関連付けます。UI デザイナーで、上部ツールバーの [信号/スロットの編集] ボタンをクリックすると、フォームは信号とスロット関数の編集状態になります。「OK」ボタン上にマウスを移動し、マウスの左ボタンを押し、フォームの空白部分に移動して左ボタンを放すと、下図のような関連付け設定ダイアログボックスが表示されるので、「OK」ボタンを関連付けます。

ここに画像の説明を挿入

同様に、btnCancel の clicked() 信号は QWDialog の raise() スロット関数に関連付けることができ、btnClose の clicked() 信号は QWDialog の close() スロット関数に関連付けることができます。

注: 右側のリスト ボックスには close() スロット関数がありません。close() 関数を表示するには、下の「QWidget から継承した信号とスロットを表示する」をチェックする必要があります。

結果は以下のようになります。

ここに画像の説明を挿入

2.4.4.2 原則の導入

3 つのボタンの信号とスロットの関連付けを設定すると、フォームの下部にあるシグマとスロット エディターにも 3 つの関連付けが表示されます。実際、関連付け設定はシグナル エディターとスロット エディターで直接行うことができます。ここでプログラムをコンパイルして実行します。これらの 3 つのボタンをクリックするとプログラムが閉じます。
では、これら 3 つのボタンの信号とスロット関数の関連付けはどこで実現されるのでしょうか? 答えは setupUi0 関数にあり、次の 3 行のコードが setupUi() 関数に自動的に追加されます。

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

上記はビジュアル UI デザインを使用してプログラムを実装しており、関連するソース コードは次のとおりです。

2.5 ソースコード

2.5.1 Dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

namespace Ui {
    
    
class Dialog;
}

class Dialog : public QDialog
{
    
    
    Q_OBJECT

public:
    explicit Dialog(QWidget *parent = 0);
    ~Dialog();

private slots:
    void on_checkBoxUnder_clicked(bool checked);

    void on_checkBoxItalic_clicked(bool checked);

    void on_checkBoxBold_clicked(bool checked);

    void setTextFontColor();

private:
    Ui::Dialog *ui;
};

#endif // DIALOG_H

2.5.2 Dialog.cpp

#include "Dialog.h"
#include "ui_Dialog.h"

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    
    
    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()));//信号与槽的关联
}

Dialog::~Dialog()
{
    
    
    delete ui;
}

void Dialog::on_checkBoxUnder_clicked(bool checked)
{
    
    
    //设置下划线
        QFont font=ui->txtEdit->font();
        font.setUnderline(checked);
        ui->txtEdit->setFont(font);
}

void Dialog::on_checkBoxItalic_clicked(bool checked)
{
    
    
    //设置斜体
        QFont   font=ui->txtEdit->font();
        font.setItalic(checked);
        ui->txtEdit->setFont(font);
}

void Dialog::on_checkBoxBold_clicked(bool checked)
{
    
    
    //设置粗体
        QFont   font=ui->txtEdit->font();
        font.setBold(checked);
        ui->txtEdit->setFont(font);
}

void Dialog::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);
}

3.コーディングUIデザイン

インターフェイス設計の最下層は実際には C++ 言語で実装されているため、最下層で実現される機能はビジュアル デザインよりも強力で柔軟です。インターフェイスの効果の中には、ビジュアル デザインでは実現できないものもあります。また、純粋なコードでインターフェイスを設計することに慣れているため、純粋なコードでインターフェイスを設計できる人もいます。たとえば、Qt に付属のサンプルでは、​​基本的に純粋なコードでユーザー インターフェイスを実装しています。

3.1 達成効果

ここに画像の説明を挿入

フレームワークは主に、コンストラクター内の次のプログラムによって実装されます。

    iniUI(); //界面创建与布局
    iniSignalSlots(); //信号与槽的关联
    setWindowTitle("Form created manually");//设置窗体标题

3.2 ソースコード

3.2.1 qwdlgmanual.h

コードに中国語の文字化けの問題があり、後で解決する予定です。

#ifndef QWDLGMANUAL_H
#define QWDLGMANUAL_H

#include <QDialog>

#include <QCheckBox>
#include <QRadioButton>
#include <QPlainTextEdit>
#include <QPushButton>


class QWDlgManual : public QDialog
{
    
    
    Q_OBJECT

private:
    QCheckBox   *chkBoxUnder;
    QCheckBox   *chkBoxItalic;
    QCheckBox   *chkBoxBold;

    QRadioButton    *rBtnBlack;
    QRadioButton    *rBtnRed;
    QRadioButton    *rBtnBlue;

    QPlainTextEdit  *txtEdit;

    QPushButton     *btnOK;
    QPushButton     *btnCancel;
    QPushButton     *btnClose;

    void    iniUI();//UI 鍒涘缓涓庡垵濮嬪寲
    void    iniSignalSlots();//鍒濆鍖栦俊鍙蜂笌妲界殑閾炬帴

private slots:
    void on_chkBoxUnder(bool checked); //Underline 鐨刢licked(bool)淇″彿鐨勬Ы鍑芥暟

    void on_chkBoxItalic(bool checked);//Italic 鐨刢licked(bool)淇″彿鐨勬Ы鍑芥暟

    void on_chkBoxBold(bool checked); //Bold 鐨刢licked(bool)淇″彿鐨勬Ы鍑芥暟

    void setTextFontColor(); //璁剧疆瀛椾綋棰滆壊

public:
    QWDlgManual(QWidget *parent = 0);
    ~QWDlgManual();

};

#endif // QWDLGMANUAL_H

3.2.2 qwdlgmanual.cpp

#include "qwdlgmanual.h"
#include    <QHBoxLayout>
#include    <QVBoxLayout>

void QWDlgManual::iniUI()
{
    
    
//创建 Underline, Italic, Bold三个CheckBox,并水平布局
    chkBoxUnder=new QCheckBox(tr("Underline"));
    chkBoxItalic=new QCheckBox(tr("Italic"));
    chkBoxBold=new QCheckBox(tr("Bold"));

    QHBoxLayout *HLay1=new QHBoxLayout;
    HLay1->addWidget(chkBoxUnder);
    HLay1->addWidget(chkBoxItalic);
    HLay1->addWidget(chkBoxBold);

//创建 Black, Red, Blue三个RadioButton,并水平布局
    rBtnBlack=new QRadioButton(tr("Black"));
    rBtnBlack->setChecked(true);//缺省被选中
    rBtnRed=new QRadioButton(tr("Red"));
    rBtnBlue=new QRadioButton(tr("Blue"));

    QHBoxLayout *HLay2=new QHBoxLayout;
    HLay2->addWidget(rBtnBlack);
    HLay2->addWidget(rBtnRed);
    HLay2->addWidget(rBtnBlue);

//创建 确定, 取消, 退出 三个 QPushButton, 并水平布局
    btnOK=new QPushButton(tr("OK"));
    btnCancel=new QPushButton(tr("CanCel"));
    btnClose=new QPushButton(tr("Close"));

    QHBoxLayout *HLay3=new QHBoxLayout;
    HLay3->addStretch();
    HLay3->addWidget(btnOK);
    HLay3->addWidget(btnCancel);
    HLay3->addStretch();
    HLay3->addWidget(btnClose);


//创建 文本框,并设置初始字体
    txtEdit=new QPlainTextEdit;
    txtEdit->setPlainText("Hello world\n\nIt is my demo");

    QFont   font=txtEdit->font(); //获取字体
    font.setPointSize(20);//修改字体大小为20
    txtEdit->setFont(font);//设置字体

//创建 垂直布局,并设置为主布局
    QVBoxLayout *VLay=new QVBoxLayout;
    VLay->addLayout(HLay1); //添加字体类型组
    VLay->addLayout(HLay2);//添加字体颜色组
    VLay->addWidget(txtEdit);//添加PlainTextEdit
    VLay->addLayout(HLay3);//添加按键组

    setLayout(VLay); //设置为窗体的主布局
}

void QWDlgManual::iniSignalSlots()
{
    
    
//三个颜色  QRadioButton的clicked()事件与setTextFontColor()槽函数关联
    connect(rBtnBlue,SIGNAL(clicked()),this,SLOT(setTextFontColor()));//
    connect(rBtnRed,SIGNAL(clicked()),this,SLOT(setTextFontColor()));//
    connect(rBtnBlack,SIGNAL(clicked()),this,SLOT(setTextFontColor()));//

//三个字体设置的  QCheckBox 的clicked(bool)事件与 相应的槽函数关联
    connect(chkBoxUnder,SIGNAL(clicked(bool)),this,SLOT(on_chkBoxUnder(bool)));//
    connect(chkBoxItalic,SIGNAL(clicked(bool)),this,SLOT(on_chkBoxItalic(bool)));//
    connect(chkBoxBold,SIGNAL(clicked(bool)),this,SLOT(on_chkBoxBold(bool)));//

//三个按键与窗体的槽函数关联
    connect(btnOK,SIGNAL(clicked()),this,SLOT(accept()));//
    connect(btnCancel,SIGNAL(clicked()),this,SLOT(reject()));//
    connect(btnClose,SIGNAL(clicked()),this,SLOT(close()));//
}

void QWDlgManual::on_chkBoxUnder(bool checked)
{
    
    
    QFont   font=txtEdit->font();
    font.setUnderline(checked);
    txtEdit->setFont(font);
}

void QWDlgManual::on_chkBoxItalic(bool checked)
{
    
    
    QFont   font=txtEdit->font();
    font.setItalic(checked);
    txtEdit->setFont(font);
}

void QWDlgManual::on_chkBoxBold(bool checked)
{
    
    
    QFont   font=txtEdit->font();
    font.setBold(checked);
    txtEdit->setFont(font);
}

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

    txtEdit->setPalette(plet);
}

QWDlgManual::QWDlgManual(QWidget *parent)
    : QDialog(parent)
{
    
    
    iniUI(); //界面创建与布局
    iniSignalSlots(); //信号与槽的关联
    setWindowTitle("Form created manually");//设置窗体标题
}

QWDlgManual::~QWDlgManual()
{
    
    

}

4. ハイブリッドアプローチのUIデザイン

4.1 設計目的

純粋なコードを使用した UI デザインは万能ですが、ビジュアル UI デザインはシンプルで効率的ですが、デザイン効率が低すぎてプロセスが非常に煩雑です。したがって、ビジュアルデザインで解決できる場合は可能な限りビジュアルデザインで解決し、解決できない場合は純粋なコードで解決する、この2つの方法を組み合わせるのが最も効率の良いUIデザインとなります。

このセクションでは、例を使用して、ハイブリッド方法で UI を作成する方法を説明します。つまり、一部のインターフェイス デザインは UI デザイナーを使用して視覚的に実装され、一部のインターフェイス デザインは UI デザイナーで実装できないものはコードで実装されます。同時に、一般的なアプリケーションプログラムのメインウィンドウが持つ機能である如何使用资源文件如何使用Actions、 、 についても、この例を用いて説明します。如何设计主窗口里的菜单、工具栏和状态栏

このプロジェクトのウィンドウ クラスは QMainWindow から継承され、メイン メニュー、ツールバー、ステータス バーを備えています。この例では、メイン メニュー、メイン ツールバー、ステータス バーを実装しており、テキストを編集するための TextEdit コンポーネントが中央のワークスペースにあります。下の図はUIデザイナーでデザインしたウィンドウです。
ここに画像の説明を挿入

フォント サイズを設定するために SpinBox コンポーネントをツールバーに追加し、フォント名を選択するために FontComboBox コンポーネントをツールバーに追加したいと考えています。ただし、UI デザイナーでこれらのコンポーネントをツールバーにドラッグ アンド ドロップすると、ツールバーに追加できないことが表示されます。同様に、Label コンポーネントと ProgressBar コンポーネントをフォームの下のステータス バーに直接追加することはできません。これは UI のビジュアル デザインの制限であり、一部のインターフェイス効果は実現できません。

上記の問題をコードを記述することで解決し、ステータス バーに表示機能を追加して、目的のインターフェイス効果を実現しました。次の図は、最終的なインターフェイス効果です。
ここに画像の説明を挿入

4.2 プロジェクトの作成とリソース ファイルの追加

4.2.1 プロジェクトの作成

ウィジェット アプリケーション プロジェクトを作成します。ウィザードでウィンドウ クラスを作成するときに、基本クラス QMainWindow を選択し、新しいクラスの名前を QWMainWind に設定し、フォームの生成を選択します。

4.2.2 リソースファイルの追加

アイコンはプロジェクトで使用する必要があります。Qt では、アイコンはリソース ファイルに保存されます。リソース ファイルを追加するプロセスを次の図に示します。
ここに画像の説明を挿入
ここに画像の説明を挿入
ここに画像の説明を挿入

リソースのグループ化に似たプレフィックスを追加します。
ここに画像の説明を挿入
ここに画像の説明を挿入

追加ファイル
ここに画像の説明を挿入

対応するアドレスにあるファイルをすべて選択し、コンパイルすると次のフレームが得られます。

ここに画像の説明を挿入

この時のソースコードフォルダは以下の通りです

ここに画像の説明を挿入

4.3 設計アクション

QAction は非常に便利なクラスで、インターフェイス設計時に Action を作成し、その Trigger() シグナル スロット関数を記述します。設計されたアクションを使用するのは OK 创建菜单项、工具栏按钮、OKです设置为 QToolButton 按钮的关联 Actionアクションで作成されたこれらのメニュー項目やボタンをクリックすると、アクションのスロット機能が実行されます。

以下の手順に従って、.ui の下のアクション エディターでアクション リストを作成します。
ここに画像の説明を挿入

最終設計後のアクションリストを下図に示します。

ここに画像の説明を挿入

アクションリストの作成手順の詳細については、「Qt5.9 C++ 開発ガイド」を参照してください。

4.4 メニューとツールバーのデザイン

アクションを作成した後、メイン フォームのメニューとツールバーをデザインできます。このプロジェクトのウィンドウ クラス QWMainWind は QMainWindow から継承され、メニュー バー、ツール バー、ステータス バーを備えています。

プロジェクト ファイル ディレクトリ ツリーで qwmainwind.ui をダブルクリックし、UI デザイナーでこのウィンドウを開きます。ウィンドウ上部の「ここに入力してください」と表示されているところがメニューバー、メニューバーの下がツールバー、ウィンドウの下部がステータスバーです。

4.4.1 メニューバーの作成

メニューバーの「ここに入力」と表示されている箇所をダブルクリックすると、エディットボックスが表示されますので、そこに「ファイル」など、デザインしたいメニューのグループ名を入力してEnterキーを押すと、「ファイル」メニューグループが作成され、さらに「編集」グループと「書式」グループも作成できます。

メイン メニューのグループを作成した後、インターフェイスにコンポーネントを配置するのと同じように、アクション エディターのリストからアクションをメニューの特定のグループにドラッグ アンド ドロップしてメニュー項目を作成します。メニューにセパレータを追加する必要がある場合は、「セパレータの追加」をダブルクリックしてセパレータを作成し、目的の位置にドラッグします。メニュー項目または区切り文字を削除する必要がある場合は、右クリックしてメニュー項目「削除」を選択します。メニュー設計の結果は次のようになります

ここに画像の説明を挿入

4.4.2 ツールバーの作成

ツールバーも同様の方法で設計されています。アクションをウィンドウのツールバーにドラッグ アンド ドロップすると、新しいツールバー ボタンが作成されます。ツールバーに仕切りを追加したり、ツールバー ボタンを削除したりすることもできます。メインウィンドウには最初はツールバーが 1 つしかありませんが、複数のツールバーをデザインする必要がある場合は、メインウィンドウを右クリックし、[ツールバーの追加] をクリックして新しいツールバーを作成します。

ツールバーにボタンを表示するにはさまざまな方法があります。ツールバーのtoolButtonStvleプロパティを設定するだけです。詳細については、「Qt5.9 C++開発ガイド」を参照してください。取得されたインターフェイスは次の図に示されています。

ここに画像の説明を挿入

4.4.3 QTextEdit を配置する

QTextEdit コンポーネントをオブジェクト名を txtEdit に設定してフォームに配置します。このようにして、メニューバーとツールバーのビジュアルデザインが完成します。以下に示すように

ここに画像の説明を挿入

4.4.4 ビジュアルインターフェイスの基礎となる実装

視覚的に設計されたインターフェイスの基礎となる実装は、ui qwmainwind.h ファイルによって実現されます。ui gwmainwind.h ファイルを開くと、クラス Ui_QWMainWind が ui_qwmainwind.h で定義されていることがわかります。パブリック部分では、すべてのアクションとインターフェイスのさまざまなコンポーネントのポインター変数が定義され、setupUi() 関数ですべてのアクションとインターフェイス コンポーネントが順番に作成され、アクションがメイン メニューとツールバーに追加されます。

すべてのコードを使って書くと時間がかかることが考えられます。

4.5 他のインターフェースコンポーネントを作成するコード

ツールバーに SpinBox を追加してフォント サイズを設定し、FontComboBox を追加してフォントを選択します。SpiBoxをコンポーネントパネルからツールバーにドラッグ&ドロップすると、ツールバーが「拒否」されるのと同様に、ステータスバーにLabelやProgreeBarを置くのも「拒否」されることが分かりました。これは U Designer の制限であり、一部のインターフェイス効果はビジュアル デザインでは実現できません。

4.5.1 qwmainwind.h

#ifndef QWMAINWIND_H
#define QWMAINWIND_H

#include <QMainWindow>
#include <QLabel>
#include <QProgressBar>
#include <QSpinBox>
#include <QFontComboBox>

namespace Ui {
    
    
class qwmainwind;
}

class qwmainwind : public QMainWindow
{
    
    
    Q_OBJECT

public:
    explicit qwmainwind(QWidget *parent = 0);
    ~qwmainwind();

private:
    Ui::qwmainwind *ui;

private:
    QLabel      *fLabCurFile;//状态栏里显示当前文件的Label
    QProgressBar    *progressBar1;//状态栏上的进度条

    QSpinBox        *spinFontSize;//   字体大写
    QFontComboBox   *comboFont;//字体名称

    void    iniUI(); //程序设计的UI初始化
};

#endif // QWMAINWIND_H

4.5.2 qwmainwind.cpp

#include "qwmainwind.h"
#include "ui_qwmainwind.h"

qwmainwind::qwmainwind(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::qwmainwind)
{
    
    
    ui->setupUi(this);

    iniUI();
}

qwmainwind::~qwmainwind()
{
    
    
    delete ui;
}

void qwmainwind::iniUI()
{
    
    
    //状态栏
        fLabCurFile=new QLabel;  //用于显示当前文件名的标签
        fLabCurFile->setMinimumWidth(150);
        fLabCurFile->setText(QString::fromLocal8Bit("当前文件:"));
        ui->statusBar->addWidget(fLabCurFile);//添加到状态栏

        progressBar1=new QProgressBar;//状态栏上的进度条
        progressBar1->setMaximumWidth(200);//设置组件最大宽度
        progressBar1->setMinimum(5);
        progressBar1->setMaximum(50);
        progressBar1->setValue(ui->txtEdit->font().pointSize());//初始值
        ui->statusBar->addWidget(progressBar1); //添加到状态栏

    //工具栏
        spinFontSize = new QSpinBox;// 工具栏上的文字大小 SpinBox
        spinFontSize->setMinimum(5);
        spinFontSize->setMaximum(50);
        spinFontSize->setValue(ui->txtEdit->font().pointSize());//初始值
        spinFontSize->setMinimumWidth(50);//设置组件最小宽度

        ui->mainToolBar->addWidget(new QLabel(QString::fromLocal8Bit("字体大小 "))); //不引用的Label无需定义变量
        ui->mainToolBar->addWidget(spinFontSize); //SpinBox添加到工具栏

        ui->mainToolBar->addSeparator(); //工具栏上增加分隔条
        ui->mainToolBar->addWidget(new QLabel(QString::fromLocal8Bit(" 字体 ")));
        comboFont = new QFontComboBox;//字体名称ComboBox
        comboFont->setMinimumWidth(150); //设置组件最小宽度
        ui->mainToolBar->addWidget(comboFont);//添加到工具栏

        setCentralWidget(ui->txtEdit); //将txtEdit设置为中心组件,自动填充整个工作区
}

4.5.3 コンパイルと実行の結果と通知

コンパイルして実行した後のインターフェイスを次の図に示します。
ここに画像の説明を挿入

知らせ:

iniUI() 関数は ui->setupUi(this) の後に呼び出す必要があり、2 行のステートメントの順序は変更できません。ui->setupUi(this) は視覚的に設計されたインターフェイスの作成を実現するため、iniUI() は視覚的に作成されたインターフェイスに基づいて他のコンポーネントを追加するため、その後で呼び出す必要があります。

4.6 アクションの機能実現

アクションは目に見えないインターフェイス要素であり、主にメニュー項目とツールバー ボタンのデザインに使用されます。アクションのメイン信号はtrigger()です。アクションのtrigger()信号のスロット関数を記述した後、このアクションによってメニューおよびツールバー上に作成されたメニュー項目およびツールバー・ボタンはすべて、このスロット関数に関連付けられます。

4.6.1 編集機能の実装 アクション

編集に使用されるアクションには、切り取り、コピー、貼り付け、クリアの機能があり、txtEdit コンポーネントで対応する操作を実行します。QTextEdit クラスには対応するスロット関数があり、実装コードを記述する必要はなく、Action のtrigger() 信号を txtEdit の対応するスロット関数に関連付けるだけです。Signals and Slots エディターで信号とスロットの関係を設定します。設計後のいくつかのアクションの関係は次の図に示されています。

ここに画像の説明を挿入

4.6.2 その他のアクションの機能実現

アクションの主な信号は trigger()と でtrigger(bool)、メニュー項目またはツールバー ボタンがクリックされたときに発行されます。

太字、斜体、および下線の設定に使用される 3 つのアクションには、Checkable 属性があります。スロット関数を設計するには、トリガー (ブール) 信号を選択する方が適切です。この信号は、アクションのチェック状態をパラメーターとして渡し、応答コードで直接使用できます。その他のアクションは、trigger() シグナル生成スロット関数を選択できます。アクションの「スロットに移動」ダイアログ ボックスで、アクションのスロット関数を作成する信号を選択します。

ここに画像の説明を挿入

スロット関数は自動的に生成され、コードは次のように補足されます。

void qwmainwind::on_actFontBold_triggered(bool checked)
{
    
    
    QTextCharFormat fmt; //格式
    fmt=ui->txtEdit->currentCharFormat();//获取当前选择文字的格式

    if (checked) // 相当于调用ui->actFontBold->isChecked();读取Action的check状态
        fmt.setFontWeight(QFont::Bold);
    else
        fmt.setFontWeight(QFont::Normal);

    ui->txtEdit->mergeCurrentCharFormat(fmt); 
}

コードの残りの部分はそれ自体で補足され、最終的なコードは後で提供されます。

4.6.3 アクションの有効およびチェックされたプロパティの更新

インターフェイスとプログラム機能をよりインテリジェントにするために、関連するアクションのチェック済みおよび有効化された属性は、現在の状態に応じて自動的に更新される必要があります。これはソフトウェア設計では一般的な機能です。

このプログラムでは、「切り取り」、「コピー」、「貼り付け」の有効な属性はテキストボックス内のテキスト選択の状態に応じて変化し、「太字」、「斜体」、「下線」のチェックされた属性は現在のテキストのフォントの状態に応じて自動的に更新されます。これは、QTextEdit の一部の信号にスロット関数を記述することで実現できます。
メイン フォームでテキスト編集ボックス txtEdit を選択し、ショートカット メニューの [スロットに移動] ダイアログ ボックスを呼び出します。QTextEdit のすべての信号がダイアログ ボックスにリストされ、使用可能な信号が 2 つあります。

  • copyAvailable(bool) 信号は、コピーするコンテンツがある場合に発行され、ブール値パラメーターが渡されます。このパラメーターは、actCut および actCopy の有効なプロパティを変更するために使用できます。

  • 選択されたテキストが変更されると、selectionChanged() 信号が発行され、現在のテキストの形式を読み取って、太字、斜体、下線の 3 つのフォント設定のチェックされたプロパティを更新できます。

txtEdit コンポーネントの 2 つの信号に対してスロット関数定義と関数本体フレームを生成します。動作図は次のとおりです。

ここに画像の説明を挿入

次のようにコードを記述します。

void qwmainwind::on_txtEdit_copyAvailable(bool b)
{
    
    
    //有文字可copy时更新cut,copy的Enable状态
        ui->actCut->setEnabled(b); //能否 cut
        ui->actCopy->setEnabled(b);  //能否copy

        ui->actPaste->setEnabled(ui->txtEdit->canPaste()); //能否paste
}

void qwmainwind::on_txtEdit_selectionChanged()
{
    
    
    //当前选择的文字发生变化,更新粗体、斜体、下划线3个action的checked状态
        QTextCharFormat fmt;
        fmt=ui->txtEdit->currentCharFormat(); //获取文字的格式

        ui->actFontItalic->setChecked(fmt.fontItalic()); //是否斜体
        ui->actFontBold->setChecked(fmt.font().bold()); //是否粗体
        ui->actFontUnder->setChecked(fmt.fontUnderline()); //是否有下划线

}

4.7 コードによって作成されたコンポーネントの信号とスロット

また、インターフェース上にはフォントサイズを設定するspinFontSizeと、フォントを設定するcomboFontという2つのコンポーネントがコードで作成されていますが、これら2つのコンポーネントのシグナル機能とスロット機能は、当然ながら上記の可視化手法では実現できません。コードで作成されたコンポーネントの場合、コードを使用してスロット関数を記述し、信号をスロットに関連付ける必要があります。

これを行うには、QWMainWind クラスで 2 つのスロット関数を定義し、コンストラクターで呼び出される、信号をスロットに関連付ける関数 iniSignalSlots0 を定義する必要があります。

最終的なコードは以下の通りです。

4.8 最終的な関数実装コード

4.8.1 qwmainwind.h

#ifndef QWMAINWIND_H
#define QWMAINWIND_H

#include <QMainWindow>
#include <QLabel>
#include <QProgressBar>
#include <QSpinBox>
#include <QFontComboBox>

namespace Ui {
    
    
class qwmainwind;
}

class qwmainwind : public QMainWindow
{
    
    
    Q_OBJECT

public:
    explicit qwmainwind(QWidget *parent = 0);
    ~qwmainwind();

private slots:

    void on_actFontBold_triggered(bool checked);

    void on_txtEdit_copyAvailable(bool b);

    void on_txtEdit_selectionChanged();

    void on_actFontItalic_triggered(bool checked);

    void on_actFontUnder_triggered(bool checked);

    void on_actOpen_triggered();

    void on_actNew_triggered();

    void on_actFont_triggered();

    //  自定义槽函数
    void on_spinBoxFontSize_valueChanged(int aFontSize);//改变字体大小的SpinBox的响应
    void on_comboFont_currentIndexChanged(const QString &arg1);//FontCombobox的响应,选择字体名称

private:
    Ui::qwmainwind *ui;

private:
    QString     fCurFileName;//当前文件名
    QLabel      *fLabCurFile;//状态栏里显示当前文件的Label
    QProgressBar    *progressBar1;//状态栏上的进度条

    QSpinBox        *spinFontSize;//   字体大写
    QFontComboBox   *comboFont;//字体名称

    void    iniUI(); //程序设计的UI初始化
    void    updateCurFile(QString aFile);//更新当前文件名,并更新状态栏提示

    void    iniSignalSlots(); //手工关联信号与槽
    void    createNew();
};

#endif // QWMAINWIND_H

4.8.2 qwmainwind.cpp

#include "qwmainwind.h"
#include "ui_qwmainwind.h"
#include    <QFile>
#include    <QFileDialog>
#include    <QTextStream>
#include    <QFontDialog>
#include    <QTextCharFormat>

qwmainwind::qwmainwind(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::qwmainwind)
{
    
    
    ui->setupUi(this);

    iniUI();

    iniSignalSlots();//信号与槽关联
}

qwmainwind::~qwmainwind()
{
    
    
    delete ui;
}

void qwmainwind::iniUI()
{
    
    
    //状态栏
    fLabCurFile=new QLabel;  //用于显示当前文件名的标签
    fLabCurFile->setMinimumWidth(150);
    fLabCurFile->setText(QString::fromLocal8Bit("当前文件:"));
    ui->statusBar->addWidget(fLabCurFile);//添加到状态栏

    progressBar1=new QProgressBar;//状态栏上的进度条
    progressBar1->setMaximumWidth(200);//设置组件最大宽度
    progressBar1->setMinimum(5);
    progressBar1->setMaximum(50);
    progressBar1->setValue(ui->txtEdit->font().pointSize());//初始值
    ui->statusBar->addWidget(progressBar1); //添加到状态栏

    //工具栏
    spinFontSize = new QSpinBox;// 工具栏上的文字大小 SpinBox
    spinFontSize->setMinimum(5);
    spinFontSize->setMaximum(50);
    spinFontSize->setValue(ui->txtEdit->font().pointSize());//初始值
    spinFontSize->setMinimumWidth(50);//设置组件最小宽度

    ui->mainToolBar->addWidget(new QLabel(QString::fromLocal8Bit("字体大小 "))); //不引用的Label无需定义变量
    ui->mainToolBar->addWidget(spinFontSize); //SpinBox添加到工具栏

    ui->mainToolBar->addSeparator(); //工具栏上增加分隔条
    ui->mainToolBar->addWidget(new QLabel(QString::fromLocal8Bit(" 字体 ")));
    comboFont = new QFontComboBox;//字体名称ComboBox
    comboFont->setMinimumWidth(150); //设置组件最小宽度
    ui->mainToolBar->addWidget(comboFont);//添加到工具栏

    setCentralWidget(ui->txtEdit); //将txtEdit设置为中心组件,自动填充整个工作区
}

void qwmainwind::updateCurFile(QString aFile)
{
    
    
    //更新当前文件名,并更新状态栏提示
    fCurFileName=aFile;
    fLabCurFile->setText(QString::fromLocal8Bit("当前文件:")+fCurFileName);
}

void qwmainwind::iniSignalSlots()
{
    
    
    //信号与槽的关联,当函数带有参数时,必须写明参数的类型
        connect(spinFontSize,SIGNAL(valueChanged(int)),
                this,SLOT(on_spinBoxFontSize_valueChanged(int)));

        connect(comboFont,SIGNAL(currentIndexChanged(const QString &)),
                this,SLOT(on_comboFont_currentIndexChanged(const QString &)));
}



void qwmainwind::on_actFontBold_triggered(bool checked)
{
    
    
    QTextCharFormat fmt; //格式
    fmt=ui->txtEdit->currentCharFormat();//获取当前选择文字的格式

    if (checked) // 相当于调用ui->actFontBold->isChecked();读取Action的check状态
        fmt.setFontWeight(QFont::Bold);
    else
        fmt.setFontWeight(QFont::Normal);

    ui->txtEdit->mergeCurrentCharFormat(fmt);
}

void qwmainwind::on_txtEdit_copyAvailable(bool b)
{
    
    
    //有文字可copy时更新cut,copy的Enable状态
    ui->actCut->setEnabled(b); //能否 cut
    ui->actCopy->setEnabled(b);  //能否copy

    ui->actPaste->setEnabled(ui->txtEdit->canPaste()); //能否paste
}

void qwmainwind::on_txtEdit_selectionChanged()
{
    
    
    //当前选择的文字发生变化,更新粗体、斜体、下划线3个action的checked状态
    QTextCharFormat fmt;
    fmt=ui->txtEdit->currentCharFormat(); //获取文字的格式

    ui->actFontItalic->setChecked(fmt.fontItalic()); //是否斜体
    ui->actFontBold->setChecked(fmt.font().bold()); //是否粗体
    ui->actFontUnder->setChecked(fmt.fontUnderline()); //是否有下划线

}

void qwmainwind::on_actFontItalic_triggered(bool checked)
{
    
    
    QTextCharFormat fmt;
    fmt=ui->txtEdit->currentCharFormat();
    fmt.setFontItalic(checked);
    ui->txtEdit->mergeCurrentCharFormat(fmt);
}

void qwmainwind::on_actFontUnder_triggered(bool checked)
{
    
    
    QTextCharFormat fmt;
    fmt=ui->txtEdit->currentCharFormat();
    fmt.setFontUnderline(checked);
    ui->txtEdit->mergeCurrentCharFormat(fmt);
}

void qwmainwind::on_actOpen_triggered()
{
    
    
    QString curPath,aFileName;
    curPath=QCoreApplication::applicationDirPath(); //获取应用程序的路径

    //调用打开文件对话框打开一个文件
    aFileName=QFileDialog::getOpenFileName(this,tr("打开一个文件"),curPath,
                                           "C++程序文件(*.cpp);;H头文件(*.h);;文本文件(*.txt);;所有文件(*.*)");

    if (!aFileName.isEmpty())
    {
    
    
        QFile aFile(aFileName);  //以文件方式读出
        if (aFile.open(QIODevice::ReadWrite | QIODevice::Text))
        {
    
    
            QTextStream aStream(&aFile); //用文本流读取文件
            while (!aStream.atEnd())
                ui->txtEdit->append(aStream.readLine()); //读取一个文本行
            updateCurFile(aFileName); //更新状态栏显示
        }
        aFile.close();
    }
}

void qwmainwind::on_actNew_triggered()
{
    
    
    //新建文件
    ui->txtEdit->clear();
    updateCurFile("");
}

void qwmainwind::on_actFont_triggered()
{
    
    
    bool    ok;
    QFont font = QFontDialog::getFont(&ok, this);
    if (ok)
        ui->txtEdit->setFont(font);
}

void qwmainwind::on_spinBoxFontSize_valueChanged(int aFontSize)
{
    
    
    //改变字体大小的SpinBox的响应
        QTextCharFormat fmt;
        fmt.setFontPointSize(aFontSize); //设置字体大小
        ui->txtEdit->mergeCurrentCharFormat(fmt);
        progressBar1->setValue(aFontSize);
}

void qwmainwind::on_comboFont_currentIndexChanged(const QString &arg1)
{
    
    
    //FontCombobox的响应,选择字体名称
        QTextCharFormat fmt;
        fmt.setFontFamily(arg1);//设置字体名称
        ui->txtEdit->mergeCurrentCharFormat(fmt);
}

4.8.3 qwmainwind.ui

ここに画像の説明を挿入

4.9 アプリケーションのアイコンを設定する

Qt Creator で作成したプロジェクトのコンパイル済み実行ファイルにはデフォルトのアイコンが設定されていますが、アプリケーションに独自のアイコンを設定する必要がある場合、操作は 2 ステップで非常に簡単です。

アイコン ファイル (接尾辞「ico」が付いたアイコン ファイルである必要があります) をプロジェクトのソース プログラム ディレクトリにコピーします。

プロジェクト構成ファイル (.pro ファイル) で、RC_ICONS を使用してアイコン ファイル名を設定し、次のコード行を追加します。

RC_ICONS = APPIcon.ico

このうち、「AppIcon.ico」はプロジェクトのソースプログラムディレクトリにコピーされたアイコンファイルの名前です。この設定を行うと、コンパイル後に生成される実行ファイルおよびメインウィンドウのアイコンが設定したアイコンに置き換えられます。

4.10 実行結果

ここに画像の説明を挿入

5. ソースコードのダウンロード

上記の例のソース コードは、必要に応じて、「02-0-Qt 5.9 C++ 開発ガイド - GUI アプリケーション設計の基本ソース コード」からダウンロードできます。

おすすめ

転載: blog.csdn.net/Dasis/article/details/131404067