記事ディレクトリ
序文
以前の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
もあります。MainWindow
mainwindow.h
MainWindow
クラスui 指针
インターフェイスコンポーネントを使用してビジュアルデザインにアクセスできるようにします。