Qt-UIのレイアウトとコントロールの使用を開始する

序文

以前のAndroidの学習経験を考慮して、Qt学習を次のステップに分割しました。

  • UI
  • 信号とスロット
  • グローバル化
  • マルチスレッド
  • ファイル操作
  • データベース
  • ネットワークプログラミング

UI、信号、スロットに精通している場合は、犬のように見えるものを書くことができるはずです。

Qt一般的に使用されるコントロールと分類

ここに写真の説明を挿入
Qt Designerに直接慣れることをお勧めします。コントロールは多くなく、コーディングは必要ありません。

興味のある方は、以下の制御特性などに精通しています。興味がない場合は、計算機の引き出し方を学んでください。

それでも他の人の話を聞きたい場合は、このクレイジーなAberdeen Embeddedを直接見てください-エントリのqt作成者(a)

QtDesignerで作成されたコントロールオブジェクトを取得する方法

Qt Designerで作成されたコントロールをどのように取得する必要がありますか?

たとえばmainwindow.ui、でラベルが生成さ
ここに写真の説明を挿入
mainwindow.cppそのプロパティを確認することで見つけることができます。次に、で、コンストラクタでui->ObjectName(类似控件ID)コントロール取得できます。

制御を取得するための操作は、ui->setupUi(this)に書き込む必要があることに注意してください

//mainwindow.h
#include <QLabel>

//.....

class MainWindow : public QMainWindow
{
    
    
	///.....
private:
    Ui::MainWindow *ui;
    QLabel *m_label;
};

//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);
    m_label = ui->label;
}

純粋に手動でコントロールを追加する

mainwindow.hその中で使用される制御変数を定義します。

コントロールはとして定義されていることに注意してください控件类型 *控件变量名

mainwindow.cppファイルで、ui->setupUi(this)後でコントロールを作成ます

制御変数の作成方法は控件变量名 = new 控件类型であることに注意してください

必要に応じて、ここでコントロールプロパティを設定できます。

最後に、コントロールをレイアウトに追加することを忘れないでください。現在メソッドを持つレイアウトのみが見つかりましたaddWidget()

//mainwindow.h
#include <QLabel>

//.....

class MainWindow : public QMainWindow
{
    
    
	///.....
private:
    Ui::MainWindow *ui;
    QLabel *m_label;
};

//mainwindow.cpp
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    
    
    ui->setupUi(this);
    //新建一个Label
    m_label = ui->label;
    //设置属性
    m_label->setText("Hello");
    //添加到布局,verticalLayout为Qt Designer中添加的一个布局
    ui->verticalLayout->addWidget(m_label);
}

QtDesignerはどのように機能しますか

Qt Designerアフターに精通し、手動でコントロールを追加すると、そのような混乱が発生するかどうかだけでなく、QtがC++ベースになっていることがわかり、編集モードでQt Designer生成さ*.uiれたものはhtml、タブ付きのコードに似ていることがわかります。それでは、*.uiどのように機能するのでしょうか。

実際、Qt Designerデザイン*.uiファイルを使用するuic工具と、*.hファイルに変換できます(このようなui_*.hファイルのコンパイル時に自動的に生成されます)

私は自分のmainwindow.cpp存在を次のように見つけました

#include "ui_mainwindow.h"

注:自動生成にui_xxx.h基づいてQt Designer、コンパイラーは再生成されるため、手動で変更しても意味がありません。したがって、通常、プロジェクトカタログには表示されません。

ui_xxx.h 通常、次のものを含めます。

  • クラスはui_xxxx、ビジュアルデザインインターフェイスをカプセル化するために定義されます。

  • インターフェイスの各コンポーネントのメンバー変数の定義は自動的に生成されます。public各コンポーネント部分では、ポインタ変数インターフェイスとして定義されており、クラス名はQt Designer設定されたインターフェイスObjectNameです。

    注:通常、フォームのクラス名を変更することはお勧めしません。インスタンス名はフォームコードで定義する必要があります。

  • 定義されたsetupUi()関数(丸で囲んだフォーカス)、私はその関数に非常に精通している必要があると信じています。それmainwindow.cppは意志と呼ばれます。フロントも言った、C++コード取得したいのはU控件後でここにある必要があります。

  • setupUi()またretranslateUi(Widget)、ラベルテキスト、ボタンテキスト、ウィンドウタイトルなど、インターフェイスの各コンポーネントのテキストコンテンツプロパティを設定するためにも呼び出されます。

  • setupUi() 特別に見えるコード行とも呼ばれます(これは単に異なる色の花火です)

    QMetaObject::connectSlotsByName(MainWindow);

    この関数の正式な説明は次のとおりです。
    ここに写真の説明を挿入
    要するに、使用されているサブクラスを検索し、対応する信号とスロットをリンクします。

ソースについて読んでください、私はQt Creator直接ジャンプする方法を見つけることができませんダウンロードする必要なしに最後の唯一の代替のWoboqオンラインC / C ++ブラウザ、すぐに使える、使い果たされて実行された。

QMetaObject::connectSlotsByName ソースコードの内容は次のとおりです。

void QMetaObject::connectSlotsByName(QObject *o)
{
    
    
    if (!o)
        return;
    const QMetaObject *mo = o->metaObject();
    Q_ASSERT(mo);
    const QObjectList list = // list of all objects to look for matching signals including...
            o->findChildren<QObject *>(QString()) // all children of 'o'...
            << o; // and the object 'o' itself
    // for each method/slot of o ...
    for (int i = 0; i < mo->methodCount(); ++i) {
    
    
        const QByteArray slotSignature = mo->method(i).methodSignature();
        const char *slot = slotSignature.constData();
        Q_ASSERT(slot);
        // ...that starts with "on_", ...
        if (slot[0] != 'o' || slot[1] != 'n' || slot[2] != '_')
            continue;
        // ...we check each object in our list, ...
        bool foundIt = false;
        for(int j = 0; j < list.count(); ++j) {
    
    
            const QObject *co = list.at(j);
            const QByteArray coName = co->objectName().toLatin1();
            // ...discarding those whose objectName is not fitting the pattern "on_<objectName>_...", ...
            if (coName.isEmpty() || qstrncmp(slot + 3, coName.constData(), coName.size()) || slot[coName.size()+3] != '_')
                continue;
            const char *signal = slot + coName.size() + 4; // the 'signal' part of the slot name
            // ...for the presence of a matching signal "on_<objectName>_<signal>".
            const QMetaObject *smeta;
            int sigIndex = co->d_func()->signalIndex(signal, &smeta);
            if (sigIndex < 0) {
    
    
                // if no exactly fitting signal (name + complete parameter type list) could be found
                // look for just any signal with the correct name and at least the slot's parameter list.
                // Note: if more than one of thoses signals exist, the one that gets connected is
                // chosen 'at random' (order of declaration in source file)
                QList<QByteArray> compatibleSignals;
                const QMetaObject *smo = co->metaObject();
                int sigLen = qstrlen(signal) - 1; // ignore the trailing ')'
                for (int k = QMetaObjectPrivate::absoluteSignalCount(smo)-1; k >= 0; --k) {
    
    
                    const QMetaMethod method = QMetaObjectPrivate::signal(smo, k);
                    if (!qstrncmp(method.methodSignature().constData(), signal, sigLen)) {
    
    
                        smeta = method.enclosingMetaObject();
                        sigIndex = k;
                        compatibleSignals.prepend(method.methodSignature());
                    }
                }
                if (compatibleSignals.size() > 1)
                    qWarning() << "QMetaObject::connectSlotsByName: Connecting slot" << slot
                               << "with the first of the following compatible signals:" << compatibleSignals;
            }
            if (sigIndex < 0)
                continue;
            // we connect it...
            if (Connection(QMetaObjectPrivate::connect(co, sigIndex, smeta, o, i))) {
    
    
                foundIt = true;
                // ...and stop looking for further objects with the same name.
                // Note: the Designer will make sure each object name is unique in the above
                // 'list' but other code may create two child objects with the same name. In
                // this case one is chosen 'at random'.
                break;
            }
        }
        if (foundIt) {
    
    
            // we found our slot, now skip all overloads
            while (mo->method(i + 1).attributes() & QMetaMethod::Cloned)
                  ++i;
        } else if (!(mo->method(i).attributes() & QMetaMethod::Cloned)) {
    
    
            // check if the slot has the following signature: "on_..._...(..."
            int iParen = slotSignature.indexOf('(');
            int iLastUnderscore = slotSignature.lastIndexOf('_', iParen-1);
            if (iLastUnderscore > 3)
                qWarning("QMetaObject::connectSlotsByName: No matching signal for %s", slot);
        }
    }
}

コアロジックは、サブオブジェクトをトラバースし、サブオブジェクトによって引き起こされた信号を検索し、それらをon_control name(ID)_signal nameと照合し、一致する場合はconnect()を使用して接続することです。

要約setUi( )すると、フォームでのコンポーネントの作成、プロパティ設定、および信号とスロットの関連付けが実現されます。

  • 最後に、名前名がありますUi
namespace Ui {
    
    
    class MainWindow: public Ui_MainWindow {
    
    };
} // namespace Ui

MainWindowから継承するクラス内にありUi_MainWindowます。
また、宣言するためだけクラスmainwindow.hもあります。MainWindowmainwindow.h

MainWindowクラスui 指针インターフェイスコンポーネントを使用してビジュアルデザインにアクセスできるようにします。

おすすめ

転載: blog.csdn.net/weixin_40774605/article/details/105149204