初識——QT

QT安裝方法

一、項目創建流程
  1. 創建項目

    • 入口:通過Qt Creator的歡迎頁面或菜單欄(文件→新建項目)創建新項目。

    • 項目類型:選擇「Qt Widgets Application」。

    • 路徑要求:項目路徑需為純英文且不含特殊字符。

    • 構建系統:默認選擇?CMake

    • 類配置:默認生成MainWindow類(包含UI文件)。

  2. 配置構建套件

    • 選擇適用于當前平臺的構建套件(如MinGW/MSVC)。

    • 若CMake配置失敗,需檢查CMake路徑或更新組件。

  3. 運行項目

    • 點擊「運行」按鈕,生成默認窗口界面(含一個空Widget)。

二、工程文件解析
  1. CMakeLists.txt

    • 核心作用:定義項目構建規則、依賴關系及編譯選項。

    • 關鍵配置

      cmake_minimum_required(VERSION 3.10)  # 指定CMake最低版本
      project(qt01 VERSION 0.1 LANGUAGES CXX)  # 設置項目名稱及語言
      set(CMAKE_CXX_STANDARD 17)  # 指定C++標準為C++17
      find_package(Qt6 REQUIRED COMPONENTS Widgets)  # 引入Qt6 Widgets模塊
      add_executable(qt01 main.cpp)  # 定義可執行文件
      target_link_libraries(qt01 PRIVATE Qt6::Widgets)  # 鏈接Qt庫
    • 注意事項:需通過find_package引入所需Qt模塊(如Widgets、Core等)。

  2. mainwindow.h

    • 功能:聲明主窗口類,繼承自QMainWindow

    • 關鍵代碼

      #include <QMainWindow>
      namespace Ui { class MainWindow; }  // 前向聲明UI類
      class MainWindow : public QMainWindow {Q_OBJECT  // 必須包含Q_OBJECT宏以支持信號與槽
      public:MainWindow(QWidget *parent = nullptr);~MainWindow();
      private:Ui::MainWindow *ui;  // UI對象指針
      };
  3. mainwindow.cpp

    • 功能:實現主窗口類的構造函數和析構函數。

    • 關鍵代碼

      #include "mainwindow.h"
      #include "ui_mainwindow.h"
      MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {ui->setupUi(this);  // 初始化UI(自動生成)
      }
      MainWindow::~MainWindow() { delete ui; }  // 釋放UI對象
  4. main.cpp

    • 功能:應用程序入口,創建主窗口并啟動事件循環。

    • 關鍵代碼

      #include "mainwindow.h"
      #include <QApplication>
      int main(int argc, char *argv[]) {QApplication a(argc, argv);  // 管理GUI程序生命周期MainWindow w;w.show();  // 顯示窗口return a.exec();  // 進入事件循環
      }
    • 注意a.exec()是Qt事件循環的核心,負責處理用戶輸入和窗口事件。

  5. ui_mainwindow.h

    • 功能:由Qt Designer自動生成的UI布局代碼,描述窗口中的控件及其屬性。

三、Qt內存管理機制
  1. 父子對象關系

    • 規則:父對象銷毀時自動刪除所有子對象。

    • 示例

      QWidget *parent = new QWidget;
      QPushButton *button = new QPushButton(parent);  // button的父對象為parent
      delete parent;  // 自動刪除button
  2. 智能指針

    • QScopedPointer:作用域內自動釋放內存。

    • QSharedPointer:引用計數智能指針,共享所有權。

四、UI設計與信號槽
  1. 拖拽控件

    • 通過Qt Designer在.ui文件中拖拽控件(如按鈕、標簽)并設置屬性(如文本、大小)。

    • 示例:設置按鈕文本:

      ui->pushButton->setText("點我");
  2. 自動連接槽函數

    • 命名規則on_控件對象名_信號名()

    • 示例:按鈕點擊槽函數:

      void MainWindow::on_pushButton_clicked() {qDebug() << "按鈕被點擊";
      }
五、注意事項
  1. 路徑規范:避免中文和特殊字符,防止構建失敗。

  2. CMake配置:確保正確引入Qt模塊(如Widgets、Core)。

  3. 內存管理:優先使用父子對象關系或智能指針,避免內存泄漏。

  4. UI更新:修改.ui文件后需重新構建以生成ui_*.h文件。

信號與槽機制

一、概述
  • 核心作用:Qt的信號與槽機制是用于對象間通信的松耦合方式,替代傳統回調函數。當對象狀態變化(事件)時發送信號,連接的槽函數自動響應。

  • 特點:支持多對多連接(一個信號可綁定多個槽,多個信號可綁定一個槽),支持跨線程通信,參數類型需兼容。?

二、信號與槽的定義
  1. 信號(Signal)

    • 聲明方式:在類中使用?signals?關鍵字聲明,無返回值(void),無需實現。

    • 示例:?

      class MyClass : public QObject {Q_OBJECT
      signals:void mySignal(int value); // 信號聲明
      };
  2. 槽(Slot)

    • 聲明方式:在類中使用?public/private/protected slots?聲明,是普通成員函數,可帶參數和返回值。

    • 示例:

      class MyClass : public QObject {Q_OBJECT
      public slots:void mySlot(int data); // 槽聲明
      };?
三、信號的發送與槽的調用
  • 信號發送:通過?emit?關鍵字觸發信號。

    emit mySignal(100); // 發送信號
  • 槽調用規則

    • 槽函數按連接順序依次執行。

    • 槽可以是私有函數,但通過信號連接仍可調用。?

四、信號與槽的連接方式
  1. 手動連接

    • 使用?QObject::connect?函數,語法:

      connect(sender, &SenderClass::signal, receiver, &ReceiverClass::slot);
    • 示例:

      connect(ui->pushButton, &QPushButton::clicked, this, &MainWindow::handleClick);
  2. 自動連接

    • 通過槽函數命名規則?on_對象名_信號名,需在?setupUi?中調用?QMetaObject::connectSlotsByName

    • 示例:

      void MainWindow::on_pushButton_clicked() { ... } // 自動連接?
五、連接類型與規則
  1. 連接類型Qt::ConnectionType

    類型描述
    AutoConnection默認,根據線程自動選擇?Direct(同線程)或?Queued(跨線程)。
    DirectConnection立即執行,槽在發送者線程運行。
    QueuedConnection異步執行,槽在接收者線程事件循環中調用。
    BlockingQueuedConnection同步執行,發送者線程阻塞直到槽完成(需跨線程)。
    UniqueConnection避免重復連接,與上述類型按位或使用。
  2. 參數規則

    • 信號參數數量 ≥ 槽參數數量,且類型兼容。

    • 示例:

      // 合法:信號參數多于槽
      connect(obj1, &ClassA::signal(int, QString), obj2, &ClassB::slot(int));
      // 非法:槽參數多于信號
      connect(obj1, &ClassA::signal(int), obj2, &ClassB::slot(int, QString));?
六、自定義信號與槽的條件
  1. 類必須直接或間接繼承?QObject

  2. 類聲明中需包含?Q_OBJECT?宏。

  3. 信號用?signals?聲明,槽用?slots?聲明。?

七、元對象編譯器(moc)
  • 作用:處理 Qt 的擴展語法(如信號與槽),生成元對象代碼(moc_*.cpp)。

  • 必要性:包含?Q_OBJECT?的類必須通過?moc?編譯,否則信號與槽無法正常工作。?

八、關鍵示例
// 信號與槽定義
class Worker : public QObject {Q_OBJECT
signals:void progressUpdated(int percent);
public slots:void doWork() { // 工作邏輯emit progressUpdated(50); }
};// 連接
Worker worker;
QObject::connect(&worker, &Worker::progressUpdated, this, [](int percent) {qDebug() << "Progress:" << percent;
});?

簡單示例:

teacher.h:

// teacher.h
#include <QObject>
class Teacher : public QObject {Q_OBJECT
public:explicit Teacher(QObject *parent = nullptr) : QObject(parent) {}signals:void hungry();  // 正確信號聲明
};

student.h:

// student.h
#include <QObject>
#include <QDebug>
class Student : public QObject {Q_OBJECT
public:explicit Student(QObject *parent = nullptr) : QObject(parent) {}public slots:void treat();   // 槽函數聲明
};

student.cpp:

// student.cpp
#include "student.h"
void Student::treat() {qDebug() << "Student treats teacher";  // 修正輸出內容
}

window.h:

// window.h
#include <QWidget>
#include "teacher.h"
#include "student.h"class Window : public QWidget {Q_OBJECT
public:explicit Window(QWidget *parent = nullptr);public slots:void xiake();  // 觸發信號的方法private:Teacher *teacher;Student *student;
};

window.cpp:?

// window.cpp
#include "window.h"Window::Window(QWidget *parent) : QWidget(parent) {teacher = new Teacher(this);student = new Student(this);// 正確連接信號與槽(注意信號拼寫)connect(teacher, &Teacher::hungry, student, &Student::treat);
}void Window::xiake() {emit teacher->hungry();  // 觸發信號
}
九、注意事項
  1. 線程安全:跨線程通信優先使用?QueuedConnection

  2. 命名規范:自動連接槽需嚴格遵循?on_對象名_信號名?格式。

  3. 內存管理:避免循環引用,確保對象生命周期可控。

Qt事件處理總結與歸納

一、事件簡介
  1. 概念

    • 事件是用戶或系統產生的交互操作,通過事件循環處理,用于對象間信息交互。

    • Qt將系統消息轉換為QEvent對象,所有QObject子類均可處理事件。

  2. 常見事件類型

    • 用戶界面事件:鼠標事件(QMouseEvent)、鍵盤事件(QKeyEvent)、觸摸事件(QTouchEvent)。

    • 系統事件:定時器事件(QTimerEvent)、窗口事件(QResizeEvent)、繪圖事件(QPaintEvent)。

    • 自定義事件:繼承QEvent實現,用于特定需求。

二、事件處理機制
  1. 事件分發流程

    • 事件隊列:操作系統消息被轉換為QEvent,由QCoreApplication::exec()驅動的主事件循環處理。

    • 事件傳遞

      1. 事件先傳遞到焦點控件。

      2. 若未被處理,逐級傳遞給父控件。

  2. 事件處理函數

    • 子類可重寫event()函數或特定事件處理函數(如mousePressEvent())。

    • 示例:自定義按鈕重寫鼠標事件:

      // 繼承QPushButton并重寫mousePressEvent
      void CustomPushButton::mousePressEvent(QMouseEvent *e) {qDebug() << "Custom按鈕被按下";QPushButton::mousePressEvent(e); // 調用父類實現,確保信號正常觸發
      }
  3. 事件過濾器(Event Filter)

    • 作用:攔截目標對象的事件,在事件到達前處理。

    • 步驟

      1. 安裝過濾器targetObj->installEventFilter(filterObj)

      2. 重寫eventFilter():判斷事件類型并處理,返回true攔截事件,false繼續傳遞。

      bool MainWindow::eventFilter(QObject *obj, QEvent *event) {if (obj == ui->pushButton && event->type() == QEvent::MouseButtonPress) {qDebug() << "攔截按鈕點擊";return true; // 阻止事件傳遞}return QMainWindow::eventFilter(obj, event); // 默認處理
      }
三、事件與信號的區別
特性事件(QEvent)信號(Signal)
觸發方式由系統或用戶操作觸發由對象主動發出(如按鈕點擊觸發clicked
處理機制通過事件隊列分發,可被過濾或攔截直接調用連接的槽函數
靈活性可自定義事件類型和分發邏輯信號與槽通過connect綁定,不可攔截
典型應用底層交互(如鼠標移動、鍵盤輸入)邏輯響應(如按鈕點擊后的業務邏輯)
四、QEventLoop 的應用
  1. 作用

    • 在局部范圍內啟動事件循環,用于等待異步操作完成(如定時器、對話框關閉)。

  2. 使用場景

    • 等待定時器

      QEventLoop loop;
      QTimer::singleShot(3000, &loop, &QEventLoop::quit);
      loop.exec(); // 阻塞3秒后繼續執行
    • 模態對話框

      QDialog dialog;
      QEventLoop loop;
      connect(&dialog, &QDialog::finished, &loop, &QEventLoop::quit);
      dialog.show();
      loop.exec(); // 等待對話框關閉
五、常見問題與解決
  1. 頭文件缺失

    • 錯誤customepushbutton.h: No such file or directory

    • 解決:在CMake中添加包含目錄:

      include_directories(${PROJECT_SOURCE_DIR})
  2. 類型轉換錯誤

    • 錯誤invalid conversion from 'QWidget' to 'QPushButton'

    • 解決:確保自定義控件繼承自正確的基類(如QPushButton)。

  3. 信號未觸發

    • 原因:重寫事件處理函數時未調用父類實現。

    • 解決:在自定義的mousePressEvent中調用QPushButton::mousePressEvent(e)

六、總結
  • 事件處理核心:理解事件分發流程、重寫事件函數、使用過濾器攔截事件。

  • 事件與信號結合:事件處理底層交互,信號驅動業務邏輯,兩者互補。

  • 開發注意事項

    • 繼承控件時確保調用父類事件函數以維持原有邏輯。

    • 使用QEventLoop避免主線程阻塞,保持界面流暢。

    • 合理使用事件過濾器實現復雜交互邏輯。

?

  • 這是本人的學習筆記不是獲利的工具,小作者會一直寫下去,希望大家能多多監督我
  • 文章會每攢夠兩篇進行更新發布(受平臺原因,也是希望能讓更多的人看見)
  • 感謝各位的閱讀希望我的文章會對諸君有所幫助

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/81251.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/81251.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/81251.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

7-15 計算圓周率

π?131?352!?3573!??357?(2n1)n!?? 輸入格式&#xff1a; 輸入在一行中給出小于1的閾值。 輸出格式&#xff1a; 在一行中輸出滿足閾值條件的近似圓周率&#xff0c;輸出到小數點后6位。 輸入樣例&#xff1a; 0.01輸出樣例&#xff1a; 3.132157 我的代碼 #i…

【圖片識別工具】批量單據識別批量重命名,批量OCR識別圖片文字并重命名,批量改名工具的使用步驟和注意事項

一、適用場景 ??財務與發票管理??&#xff1a;企業需處理大量電子發票或掃描件&#xff0c;通過OCR識別發票代碼、金額等關鍵信息&#xff0c;自動重命名為發票號_金額.pdf格式&#xff0c;便于歸檔與稅務審計。 ??物流單據處理??&#xff1a;物流公司需從運單中提取單…

Modbus TCP轉Profinet網關:數字化工廠異構網絡融合的核心樞紐

在現代工業生產中&#xff0c;隨著智能制造和工業互聯網的不斷發展&#xff0c;數字化工廠成為了制造業升級的重要方向。數字化工廠的核心在于實現設備、數據和人的互聯互通&#xff0c;而這其中&#xff0c;通信協議扮演著至關重要的角色。今天&#xff0c;我們就來探討開疆智…

win11平臺下的docker-desktop中的volume位置問題

因為需要搞個本地的mysql數據庫&#xff0c;而且本地安裝的程序較多&#xff0c;不想再安mysql了&#xff0c;就想到使用docker來安裝。而且因為數據巨大&#xff0c;所以想到直接使用轉移data文件夾的方式。 各種查詢&#xff0c;而且還使用ai查詢&#xff0c;他們都提到&…

【MySQL】項目實踐

個人主頁&#xff1a;Guiat 歸屬專欄&#xff1a;MySQL 文章目錄 1. 項目實踐概述1.1 項目實踐的重要性1.2 項目中MySQL的典型應用場景 2. 數據庫設計流程2.1 需求分析與規劃2.2 設計過程示例2.3 數據庫設計工具 3. 電子商務平臺實踐案例3.1 系統架構3.2 數據庫Schema設計3.3 數…

React學習———CSS Modules(樣式模塊化)

CSS Modules CSS Modules&#xff08;樣式模塊化&#xff09;是一種用于模塊化和局部作用域化CSS樣式的技術&#xff0c;讓CSS只在當前組件內生效&#xff0c;避免全局樣式沖突的技術方案 工作原理 文件命名&#xff1a;通常以.module.css、.module.less、.module.scss等結尾…

agent 智能體應用產品:生圖、生視頻、代碼等

生圖片 Lovart&#xff1a;全球首個設計 Agent https://www.lovart.ai/ 生視頻 AI 視頻 Agent 產品&#xff1a;Medeo https://www.medeo.app/ 代碼 vscode copilot、cursor、trae 其他research manus grok等各個大模型產品

青少年ctf平臺應急響應-應急響應2

題目&#xff1a; 當前服務器被創建了一個新的用戶&#xff0c;請提交新用戶的用戶名&#xff0c;得到的結果 ssh rootchallenge.qsnctf.com -p 30327 這個命令用于通過 SSH 協議連接到指定的遠程服務器。具體解釋如下&#xff1a; ssh&#xff1a;這是在 Unix-like 系統中…

碼蹄集——圓包含

MT1181 圓包含 輸入2個圓的圓心的坐標值&#xff08;x&#xff0c;y&#xff09;和半徑&#xff0c;判斷斷一個圓是否完全包含另一個圓&#xff0c;輸出YES或者NO。另&#xff1a;內切不算做完全包含。 格式 輸入格式&#xff1a;輸入整型&#xff0c;空格分隔。 每行輸入一組…

基于EMD-PCA-LSTM的光伏功率預測模型研究

摘要 本文提出了一種結合經驗模態分解(EMD)、主成分分析(PCA)和長短期記憶網絡(LSTM)的混合預測模型,用于提高光伏功率預測的準確性。該模型首先利用EMD算法將非平穩的光伏功率序列分解為多個本征模態函數(IMF),然后通過PCA對多維氣象特征進行降維處理,最后將處理后的特征輸…

MYSQL創建索引的原則

創建索引的原則包括&#xff1a; 表中的數據量超過10萬以上時考慮創建索引。 選擇查詢頻繁的字段作為索引&#xff0c;如查詢條件、排序字段或分組字段。 盡量使用復合索引&#xff0c;覆蓋SQL的返回值。 如果字段區分度不高&#xff0c;可以將其放在組合索引的后面。 對于…

vue+threeJS 大理石貼圖

嗨&#xff0c;我是小路。今天主要和大家分享的主題是“vuethreeJS 大理石貼圖”。 通過 Vue 3 和 Three.js 實現大理石紋理效果&#xff0c;并將這種技術應用于產品展示、虛擬展覽、甚至是互動游戲之中&#xff0c;其潛力無窮。今天主要介紹基礎的大理石貼圖。 vueth…

依賴倒轉原則:Java 架構設計的核心準則

在軟件開發的漫長演進歷程中&#xff0c;設計原則如同燈塔般指引著工程師構建可維護、可擴展的系統。其中&#xff0c;依賴倒轉原則&#xff08;Dependency Inversion Principle, DIP&#xff09;作為面向對象設計的五大核心原則之一&#xff0c;深刻影響著系統架構的穩定性與靈…

使用Frp搭建內網穿透,外網也可以訪問本地電腦。

一、準備 1、服務器&#xff1a;需要一臺外網可以訪問的服務器&#xff0c;不在乎配置&#xff0c;寬帶好就行。我用的是linux服務器。&#xff08;一般買一個1核1g的云服務器就行&#xff09;&#xff0c;因為配置高的服務器貴&#xff0c;所以這是個擇中辦法。 2、客戶端&a…

Spyglass:跨時鐘域同步(同步使能)

相關閱讀 Spyglasshttps://blog.csdn.net/weixin_45791458/category_12828934.html?spm1001.2014.3001.5482 簡介 同步使能方案主要用于數據信號跨時鐘域同步&#xff0c;該方案將一個控制信號同步至目標時鐘域并用其作為數據信號的捕獲觸發器的使能信號&#xff0c;如圖1所示…

人工智能 (AI) 在無線接入網絡 (RAN) 中的變革性作用

隨著電信行業向更智能、更高效的系統邁進&#xff0c;將 AI 集成到 RAN 中已不再是可有可無&#xff0c;而是至關重要。 隨著 6G 時代的到來&#xff0c;人工智能 (AI) 有望降低運營成本&#xff0c;并帶來更大的盈利機會。AI-RAN 正處于這一變革的前沿&#xff0c;在 RAN 環境…

多線程代碼案例-2 阻塞隊列

阻塞隊列 通過數據結構的學習&#xff0c;我們都知道了隊列是一種“先進先出”的數據結構。阻塞隊列&#xff0c;是基于普通隊列&#xff0c;做出擴展的一種特殊隊列。 特點 1、線程安全的 2、具有阻塞功能&#xff1a;1、如果針對一個已經滿了的隊列進行入隊列&#xff0c…

【筆記】記一次PyCharm的問題反饋

#工作記錄 最近更新至 PyCharm 社區版的最新版本后&#xff0c;我遇到了多個影響使用體驗的問題。令人感到不便的是&#xff0c;一些在舊版本中非常便捷的功能&#xff0c;在新版本中卻變得操作復雜、不夠直觀。過去&#xff0c;我一直通過 PyCharm 內置的故障報告與反饋機制反…

學習以任務為中心的潛動作,隨地采取行動

25年5月來自香港大學、OpenDriveLab 和智元機器人的論文“Learning to Act Anywhere with Task-centric Latent Actions”。 通用機器人應該在各種環境中高效運行。然而&#xff0c;大多數現有方法嚴重依賴于擴展動作標注數據來增強其能力。因此&#xff0c;它們通常局限于單一…

相關行業發展趨勢寫一個爬蟲程序

前兩篇我利用爬蟲進行營銷推廣&#xff0c;并且寫了一個品牌口碑爬蟲的代碼示例。現在根據轉向行業發展趨勢&#xff0c;可能是希望收集數據來分析市場動向、競爭對手動態或者新興技術趨勢。 技術實現方面&#xff0c;需要選擇合適的工具和庫。Python的requests和BeautifulSou…