- 創建QT文件步驟
這是創建之后widget.cpp和widget.h文件的具體代碼解釋,也是主要操作的文件,其中main.cpp不用操作,ui則是圖形化操作界面,綜合使用時,添加一個元件要注意重編名和編譯一下,才能在widget這類文件中提示出來
//widget.h
#ifndef WIDGET_H // 如果沒有定義WIDGET_H宏,則定義它。這個宏防止頭文件被多次包含。
#define WIDGET_H // 定義WIDGET_H宏。#include <QWidget> // 包含Qt庫中的QWidget類的頭文件。QWidget是所有UI對象的基類。QT_BEGIN_NAMESPACE // 開始Qt命名空間的定義。
namespace Ui { class Widget; } // 前向聲明Ui命名空間中的Widget類。這個類是由Qt Designer生成的,用于管理UI。
QT_END_NAMESPACE // 結束Qt命名空間的定義。class Widget : public QWidget // 定義Widget類,繼承自QWidget類。
{Q_OBJECT // 這是一個Qt宏,啟用Qt的信號和槽機制。public:Widget(QWidget *parent = nullptr); // 構造函數,接受一個父窗口指針,默認值為nullptr(空指針)。~Widget(); // 析構函數,銷毀Widget對象。
//可以在這里聲明信號槽函數,不過要添加關鍵字public slot:,類同publicprivate:Ui::Widget *ui; // 指向Ui::Widget對象的指針,用于管理用戶界面。
};#endif // WIDGET_H // 結束WIDGET_H宏的條件編譯。
//widget.cpp
#include "widget.h" // 包含當前類的頭文件,這個文件中定義了Widget類的聲明和成員函數原型。
#include "ui_widget.h" // 包含由Qt用戶界面設計工具(Qt Designer)生成的頭文件,這個文件中定義了Ui::Widget類,負責UI元素的布局和定義。Widget::Widget(QWidget *parent): QWidget(parent) // 調用父類QWidget的構造函數,并將父窗口指針parent傳遞給它。父窗口指針用于指定當前窗口的父窗口。, ui(new Ui::Widget) // 分配內存,創建一個新的Ui::Widget對象,并將其指針賦值給成員變量ui。Ui::Widget類由Qt Designer生成,用于管理窗口小部件的布局和控件。
{ui->setupUi(this); // 調用Ui::Widget類的setupUi方法,初始化用戶界面。這會將設計器中定義的UI元素(如按鈕、標簽等)設置到當前Widget對象中。//ui上的操作元件大多也在這里使用,比如connect
}Widget::~Widget()
{delete ui; // 在析構函數中刪除ui指針指向的Ui::Widget對象,釋放其占用的內存,防止內存泄漏。
}
//在此處定義widget類中的函數
一、log輸出
- 在Qt中進行log輸出, 一般不使用c中的printf, 也不是使用C++中的cout, Qt框架提供了專門用于日志輸出的類, 頭文件名為 QDebug
- qDebug(), qWarning(), qInfo(), 和 qCritical()是用于日志記錄和調試輸出的函數。它們分別用于不同級別的日志記錄,幫助開發者在不同場景下記錄和調試信息。
- qDebug():用于開發階段的調試信息,不重要的詳細信息。
- qWarning():用于警告信息,表示有潛在問題,但不一定是致命的。
- qInfo():用于一般信息,常規運行時的狀態信息。
- qCritical():用于嚴重錯誤信息,表示重大問題或異常。
- 默認情況下日志信息是不會打印到終端窗口的, 如果想要實現這樣的效果, 必須在項目文件中添加相關的屬性信息----->打開項目文件(*.pro)找到配置項 config, 添加 console 控制臺屬性----->
CONFIG += c++11 console
二、幫助
- 將光標放在函數上,按 F2+FN 會跳轉到 函數的定義。
- 將光標放在函數上,按 Shift + F2+FN 會跳轉到函數的聲明(如果在頭文件中聲明)。
- 將光標放在函數上,按 Ctrl + Shift + U 會查找函數在項目中的所有使用情況。
- 將光標放在函數上,按 F1 +FN會打開Qt幫助窗口,顯示 函數 的詳細文檔。
三、QT中的信號槽
- 在Qt中,信號和槽機制是一種用于對象之間通信的方式,特別適用于事件驅動的編程。信號和槽機制允許一個對象發送信號并且其他對象響應這些信號,即使它們對彼此一無所知。這種機制比傳統的回調函數更靈活、更容易使用。
- 信號和槽機制的內部工作原理
- 元對象系統(MOC)
當您定義一個包含信號和槽的類時,Qt的元對象系統(MOC)會生成一些額外的代碼。這些代碼負責實現信號和槽的機制。MOC會為每個信號生成一個唯一的整數ID,并創建一個包含信號和槽信息的表。 - 連接信號和槽
當您調用connect函數時,Qt會將信號和槽的連接信息存儲在QObject的內部數據結構中。每個QObject對象都有一個指向QMetaObject的指針,QMetaObject包含了該對象的所有元數據信息,包括信號和槽的連接信息。 - 發射信號
信號被發射時,Qt會查找與該信號連接的所有槽,并依次調用它們。對于同一線程中的連接,槽函數會立即被調用。對于跨線程的連接,信號會被放入接收者所在線程的事件隊列中,等待事件循環調度執行。 - 事件隊列
Qt使用事件隊列和事件循環來管理跨線程的信號和槽連接。當跨線程信號被發射時,信號會被封裝成一個事件,并放入接收者線程的事件隊列中。接收者線程的事件循環會處理這些事件,并調用相應的槽函數。
- 連接信號和槽的函數connect()函數
函數原型(老舊的)QObject::connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));- sender:發出信號的對象的指針
- SIGNAL(signal()):發送者的信號。signal()是發送者類中的信號名稱。()內的參數可以再一次細分信號類型。
- receiver:接收者對象指針。表示在當前的類里面
- SLOT(slot()):接收者的槽函數,使用SLOT宏來指定接收者類中的槽函數。slot()是接收者類中的槽函數名稱。()內的參數可以再一次細分信號類型。
-------------------------------------------------------------------------------------------
connect函數相對于做了信號處理動作的注冊
調用conenct函數的sender對象的信號并沒有產生, 因此receiver對象的method也不會被調用
connect中的sender和recever兩個指針必須被實例化了, 否則conenct不會成功
- 在Qt中,槽函數是用于響應信號的函數。槽函數可以是任何符合簽名要求的成員函數、全局函數或靜態函數。它們在某些事件(由信號發射)發生時被調用。例如btnLogClickedSlotFun()就是自定義的槽函數。
- 信號函數:clicked()、pressed()、released(),分別是點擊,按下持續,釋放
- 自定義信號和自定義槽函數
自定義信號的要求和注意事項:信號是類的成員函數
返回值必須是 void 類型
信號的名字可以根據實際情況進行指定
參數可以隨意指定, 信號也支持重載
信號需要使用 signals 關鍵字進行聲明, 使用方法類似于public等關鍵字
信號函數只需要聲明, 不需要定義(沒有函數體實現)
在程序中發射自定義信號: 發送信號的本質就是調用信號函數
習慣性在信號函數前加關鍵字: emit, 但是可以省略不寫
emit只是顯示的聲明一下信號要被發射了, 沒有特殊含義
底層 emit == #define emit自定義槽函數的要求
槽函數必須是類的成員函數:
槽函數必須是繼承自 QObject 的類的成員函數,不能是全局函數。槽函數必須標記為 slots 或使用 Q_SLOT 關鍵字:
在類定義中,槽函數需要使用 slots 或 Q_SLOT 關鍵字標記。例如:public slots:void mySlotFunction();槽函數的參數類型和數量必須與信號匹配:
槽函數的參數類型和數量必須與連接的信號一致。例如,如果信號的簽名是 void signal(int, QString),那么槽函數的簽名也應該是 void slot(int, QString)。槽函數的訪問權限可以是 public、protected 或 private:
槽函數可以是 public、protected 或 private,這取決于類的設計和訪問控制需求。
確保信號和槽的參數類型和順序一致。如果不匹配,編譯器不會報錯,但運行時連接將失敗,信號和槽之間不會通信。
槽函數的執行時間應盡量短,不要在槽函數中執行長時間阻塞的操作,因為這可能會阻塞事件循環,導致用戶界面無響應。
如果不再需要信號和槽之間的連接,可以使用 disconnect 函數斷開它們。可以斷開特定的信號和槽,也可以斷開對象之間所有的信號和槽。小竅門(在連接處加上dis即可)
5. 一個信號可以連接多個槽函數, 發送一個信號有多個處理動作,槽函數的執行順序是隨機的, 和connect函數的調用順序沒有關系,一個槽函數可以連接多個信號, 多個不同的信號, 處理動作是相同的