文章目錄
- Qt信號槽的優點及缺點
- Qt中的文件流和數據流區別?
- Qt中show和exec區別
- QT多線程使用的方法 (4種)
- QString與基本數據類型如何轉換?
- QT保證多線程安全
- 事件與信號的區別
- connect函數的連接方式?
- 信號與槽的多種用法
- Qt的事件過濾器有哪些
- 同步和異步的網絡連接區別?
- Qt網絡模塊中有那些類來執行異步操作?
- Qt如何執行HTTP請求?
- 什么是Qt Quick?
Qt信號槽的優點及缺點
信號槽為觀察者模式。槽的本質為類成員函數,參數為任何數據類型,可以被重載,也可以是虛函數,也可以設置權限(public/private/protected)
1.Qt信號槽的優點
(1)靈活性好: 一個信號可以綁定多個槽,同時多個信號也可以關聯同一個槽,提供了高度的靈活性
(2)類型安全: 信號和槽在關聯時,必須確保它們的簽名(包括參數類型和參數個數)完全一致,否則編譯時會報錯,這保證了類型的安全性。
(3)松散耦合: 信號和槽機制減弱了QT對象之間的耦合度,使得對象之間的交互更加靈活和獨立。
2.Qt信號槽的缺點
執行速度慢: 信號和槽機制在執行時,特別是在多線程環境下,需要排隊等待和定位接收信號的對象,因此執行速度相對較慢,效率較低。
Qt中的文件流和數據流區別?
1.Qt的文件流QTextStream
(1)文本展現方式:通過QTextStream寫入文件的數據以文本方式展現,提供讀寫文本文件的接口
(2)操作對象:可以操作QIODevice、QString和QByteArray三種數據類型
(3)編碼特性:內部使用Unicode編碼處理文本數據
(4)讀取模式:
塊讀取:使用readLine()
/readAll()
函數進行整塊數據讀取
字符讀取:使用QChar
/char
逐個字符讀取(常用于文件解析場景)
(5)格式控制:
通過setFileWidth()
/setPadChar()
設置文本寬度和填充字符
通過setFileAlignment()
設置段落文本的對齊格式
(6)適用場景:特別適合處理字符、數字等文本數據的讀寫操作
2.Qt中的數據流QDataStream
(1)數據類型支持:可以操作各種數據類型,包括類對象等復雜數據結構
(2)數據持久化:保存到文件的數據可以完整還原至內存
(3)操作范圍:
磁盤文件操作
內存數據信息處理
(4)構造函數:
QDataStream()
:構造無IO設備的數據流
QDataStream(QIODevice *d)
:使用指定IO設備構造數據流
(5)關鍵控制參數:
ByteOrder
:控制讀寫字節順序
FloatingPointPrecision
:設置浮點數精度
(6)狀態檢測:
通過Status
檢測流狀態(正常/數據損壞/寫入失敗等)
使用atEnd()
檢測文件結尾
Qt中show和exec區別
1.show()針對顯示非模態對話框
非模態特性: show()用于顯示非模態對話框,不會阻塞程序線程,允許用戶同時與其他窗口交互
對象生命周期: 若對話框創建在棧上,離開作用域后對象會被銷毀,導致對話框僅短暫閃現
2.exec()針對顯示填充對話框
模態特性: exec()用于顯示模態對話框,會開啟事件循環并阻塞線程, 模態對話框在關閉前,用戶不能操作應用程序其他窗口
典型場景: 適用于必須立即處理的重要對話框,如文件保存確認
3.exec()的作用
執行流程:
進入事件循環(如return su.exec())
等待響應用戶輸入(Wait狀態)
Qt系統處理并傳遞事件/消息到各窗口
退出機制: 當程序遇到exit()時,返回exec()的值終止循環
QT多線程使用的方法 (4種)
1… QRunnable和QThreadPool結合
實現方式: 繼承QRunnable類并重寫
run()
函數,然后通過QThreadPool來運行線程
限制條件: 該方法不能使用信號和槽機制進行線程間通信
適用場景: 適合不需要與主線程頻繁交互的獨立任務
- QtConcurrentRun類
特點: 無需繼承類即可在另一個線程中執行函數
優勢: 使用簡單方便,適合快速實現多線程功能
應用場景: 特別適合在后臺線程中執行單個函數的情況
- 繼承QThread
核心操作: 通過繼承QThread類并重寫
run()
函數來實現多線程
實現要點: 需要完全重寫run()函數來定義線程執行邏輯
注意事項: 這是最傳統的QT多線程實現方式
- 繼承QObject
關鍵技術: 繼承QObject類后使用
moveToThread()
方法將對象移動到新線程
優勢: 可以充分利用QT的信號槽機制
靈活性: 允許對象在不同線程間移動,適合復雜的線程交互場景
5.操作系統線程和進程區分
系統架構: 操作系統可同時執行多個任務(進程),每個進程又可包含多個任務(線程)
執行特性: 線程之間相互獨立,采用搶占式執行方式
硬件影響:
單核CPU同一時刻只能執行一個線程
多核CPU可真正實現多線程并行
性能考量: 單核CPU上線程切換會降低執行效率,耗時操作應放在獨立線程中防止界面卡死
6.阻塞和非阻塞
非阻塞定義: 一個線程的操作不會阻塞其他線程對事件的接收和處理
阻塞現象:
公共資源同時只能被一個線程訪問
其他線程訪問會被掛起直到當前訪問結束
主線程界面刷新也可能因此被掛起
實際影響: 阻塞操作可能導致界面假死,應盡量避免在主線程中進行
7.同步和異步
同步執行: 必須等待操作完成才能繼續執行后續代碼
異步特點: 函數調用后不等待結果直接執行后續代碼
關鍵區別:
同步:等待操作完成 → 順序執行
異步:不等待結果 → 并行執行
應用建議: 耗時操作應采用異步方式避免阻塞主線程
QString與基本數據類型如何轉換?
1.QString與數字之間轉換
QString 轉換為 int: toInt()
int 轉換為 QString: QString::number(int)
// 1: QString轉換為int double floatQString qstr1("2980");int itemp1 = qstr1.toInt() + 700;qDebug()<<"itemp1="<<itemp1<<endl;// int-->QStringQString qstr2=QString::number(itemp1);qDebug()<<"qstr2="<<qstr2<<endl;
2.QDateTime與QString之間轉換
QString 轉換為 QDateTime: QDateTime::fromString(QString, QString)
QDateTime 轉換為 QString: toString(QString)(需要指定格式)
// 2: QString--->2: QDateTimeQString qstr3="2023-03-16 17:03:28";QDateTime qdatetime1=QDateTime::fromString(qstr3,"yyyy-MM-dd hh:mm:ss");qDebug()<<"qdatetime1="<<qdatetime1<<endl;// QDateTime -->QStringQDateTime qdatetime2=QDateTime::currentDateTime(); // 獲取當前時間QString qstr4=qdatetime2.toString("yyyy-MM-dd hh:mm:ss");qDebug()<<"qstr4="<<qstr4<<endl;
- QString與QByteArray之間轉換
QString 轉換為 QByteArray: toUtf8()
QByteArray 轉換為 QString: QByteArray可以直接賦值給QString
// 3: QString--->QByteArrayQString qstr5("main qt creator");QByteArray bytes1=qstr5.toUtf8();qDebug()<<"bytes1="<<bytes1<<endl;// QByteArray--->QStringQByteArray bytes2("QString ByteArray");QString qstr6=bytes2;qDebug()<<"qstr6="<<qstr6<<endl;
4.QString與char*轉換
QString 轉換為 char*: toLatin1().data()
char* 轉換為 QString: QString(QLatin1String(char*))
// 4: QString--->char*QString qstr7("Analyze Qt Creator");char* char1;QByteArray qbt=qstr7.toLatin1(); // 這步必須操作char1=qbt.data();qDebug()<<"char1="<<char1<<endl;// char*--->QStringQString qstr8=QString(QLatin1String(char1));qDebug()<<"qstr8="<<qstr8<<endl;
QT保證多線程安全
1.QT如何保證多線程安全
(1)使用互斥鎖:通過QMutex類實現資源訪問的互斥性,避免數據競爭或死鎖
(2)使用讀寫鎖:當有線程需要寫入時,其他所有線程(包括讀取線程)都會被阻塞
(3)使用信號和槽機制:避免直接操作共享數據
(4)使用顯式線程切換:通過QThread類顯式創建和管理線程,禁止直接操作線程,依賴信號槽通信
事件與信號的區別
1.什么是信號
信號是一種抽象、用于實現對象異步通信機制(由QObject類所定義)
2.什么是事件
事件是由QEvent及相關子類所定義的消息,主要用于處理對象的事件。
3.區別是什么?
(1)事件與信號的實現機制不同:①事件處理則需要通過派生和覆蓋QObject的event()函數來實現。②信號的實現由Qt框架負責。當信號被發射時,Qt的元對象系統會自動調用連接到該信號的槽函數。
(2)事件與信號的觸發機制不同:①事件則需要對象本身通過事件驅動的方式來觸發,是被動處理的。對象需要覆蓋event()函數來處理特定類型的事件。②信號是由發送對象直接通知接收對象的,是一種主動發送的機制。當信號被發射時,Qt框架會自動調用連接到該信號的槽函數。③信號就像打電話,主動通知對方。例如,按鈕點擊后會發射一個信號,通知其他對象執行相應的操作;事件就像接收郵件,需要自己去查看和處理。例如,窗口需要處理鼠標移動事件,以響應用戶的操作。
(3)事件與信號的消息類型不同:①事件有具體明確的消息類型,如單擊、雙擊等。事件對象(如QEvent及其子類)攜帶了描述整個事件的數據和事件類型。②信號是一種抽象的消息,沒有特定的類型。可以使用任意的參數來傳遞信息,使得信號非常靈活
(4)事件與信號的應用場景及時機不同:①在實現窗口部件時,我們必須考慮如何處理事件。事件更多地用于處理對象內部的具體行為,如鼠標移動、鍵盤輸入等。②在編程中,特別是使用窗口部件時,我們經常要使用信號,并遵守信號與槽之間的機制。信號通常用于對象間的異步通信,如按鈕點擊后觸發某個動作。
connect函數的連接方式?
五種類型:直接連接、自動連接、隊列連接、保留連接、自動類型轉換連接
(1)直接連接:當信號被發射時,槽函數會立即在發射信號的線程的當前執行上下文中被調用。信號發射和槽函數執行是同步的。語法如下:
QObject::connect(sender, &Sender::signal, receiver, &Receiver::slot, Qt::DirectConnection);
(2)自動連接:這是Qt的默認連接方式。Qt會根據發射信號的對象和接收槽的對象所在的線程來決定采用直接連接還是隊列連接。
①同一線程: 如果發射信號的對象和接收槽的對象位于同一個線程,則自動采用直接連接 (Direct Connection)。
②不同線程: 如果發射信號的對象和接收槽的對象位于不同的線程,則自動采用隊列連接 (Queued Connection)。QObject::connect(sender, &Sender::signal, receiver, &Receiver::slot);
(3)隊列連接:當信號被發射時,Qt不會立即執行槽函數。而是將一個包含信號信息和參數的事件(QEvent::MetaCall)放入接收槽的對象所在的線程的事件隊列中。該線程的事件循環在后續某個時刻處理這個事件時,才會調用槽函數。信號發射和槽函數執行是異步的。
QObject::connect(sender, &Sender::signal, receiver, &Receiver::slot, Qt::QueuedConnection);
(4)保留連接: 用于確保信號和槽之間最多只有一個連接。如果嘗試創建第二個連接,connect 會返回 false,并且不會創建新的連接。
QObject::connect(sender, &Sender::signal, receiver, &Receiver::slot, Qt::UniqueConnection);
(5)自動類型轉換連接:為了向后兼容舊版本的Qt而設計的。
QObject::connect(sender, &Sender::signal, receiver, &Receiver::slot, Qt::AutoCompatConnection);
(6)核心區別:
直接連接:立即執行,線程不安全但高效
自動連接:智能選擇,默認推薦方式
隊列連接:線程安全,適合跨線程
保留連接:特殊場景使用
類型轉換:兼容舊代碼
信號與槽的多種用法
信號與槽機制用于對象間通信,共有6種使用方法
1.普通方式
連接方法:直接使用connect函數將信號與槽連接
實現要點:通過函數建立標準連接關系
特點:最基本的信號槽連接方式,適用于簡單的一對一通信場景
connect(button, &QPushButton::clicked, label, &QLabel::setText);
2.一個信號連接多個槽
執行機制:當信號被觸發時,所有連接的槽函數都會被執行
注意事項:多個槽的執行順序不確定,不應依賴執行順序編寫邏輯
應用場景:適用于需要廣播通知多個接收者的情形
connect(lineEdit, &QLineEdit::textChanged, statusBar, &QStatusBar::showMessage);connect(lineEdit, &QLineEdit::textChanged, logger, &Logger::logInput);connect(lineEdit, &QLineEdit::textChanged, displayWidget, &DisplayWidget::updateDisplay);
3.帶參數的信號和槽
參數傳遞:信號可以攜帶參數傳遞給槽函數
類型匹配:連接信號和槽時,它們的參數類型必須完全匹配(或者可以隱式轉換)。參數的個數也必須一致。
語法示例: 可以通過重載信號和槽函數來實現不同參數類型的連接。
// 信號聲明 (在頭文件中)signals:void valueChanged(int newValue);void textChanged(const QString &newText);// 槽函數聲明 (在頭文件中)slots:void updateValue(int value);void updateText(const QString &text);// 連接示例connect(slider, &QSlider::valueChanged, this, &MyClass::updateValue);connect(lineEdit, &QLineEdit::textChanged, this, &MyClass::updateText);
4.斷開連接
斷開方法:使用QObject::disconnect()
函數來斷開之前建立的信號與槽的連接。
使用場景: 在對象的生命周期管理中,或者在需要動態改變對象間通信關系時使用。例如,當某個對象即將被銷毀時,應該斷開它發出的信號與其他對象的連接,以避免懸空指針或意外行為。
注意事項: 斷開連接后,該信號將不再觸發對應的槽函數,但其他未斷開的連接仍然有效。
// 斷開特定的信號槽連接disconnect(button, &QPushButton::clicked, label, &QLabel::setText);// 斷開 button 對象發出的所有信號與 label 對象的所有槽的連接disconnect(button, nullptr, label, nullptr);// 斷開 button 對象發出的 clicked 信號與所有接收者的連接disconnect(button, &QPushButton::clicked, nullptr, nullptr);
5.信號連接信號 (Signal Connected to Signal)
別名: 也常被稱為“信號轉發”或“信號傳遞”。
工作機制: 當源信號被發射時,目標信號也會被自動發射。
特點: 實現了信號的鏈式傳遞。可以用于信號轉發(一個對象接收信號后,將其轉發給另一個對象)或信號預處理(在信號傳遞路徑中加入處理邏輯)。
應用價值: 增強了信號處理的靈活性和模塊化程度。可以構建復雜的信號處理鏈。
6.自定義信號及槽
聲明方式:使用signals:
和slots:
關鍵字在類定義中聲明
實現步驟:
繼承自QObject
類
使用signals
關鍵字聲明信號
使用slots
關鍵字聲明槽函數
使用emit
關鍵字觸發信號
Qt的事件過濾器有哪些
核心功能: 在一個對象接收到事件前進行攔截/處理/修改的機制
實現方式: 通過QObject的eventFilter()
方法處理事件
用途:主要用于提高程序的可維護性和可擴展性
- QEvent類別
監視范圍: 僅監視特定類型事件
典型示例: 鼠標事件
特點: 事件類型針對性過濾,如鍵盤/鼠標等硬件事件- QApplication級別
監視范圍: 整個QT應用程序的所有事件
應用場景: 需要全局監控時使用
特點: 可捕獲應用啟動/退出等系統級事件- QObject級別
監視范圍: 任何QObject對象上的事件
覆蓋性: 包含但不限于QWidget對象
靈活性: 可監控所有繼承自QObject的類實例- QWidget級別
監視范圍: 僅限QWidget及其子類對象
典型應用: 窗口組件的事件處理
區別點: 比QObject范圍更專一,針對可視化組件- QGraphicsItem級別
監視范圍: 僅限QWidget及其子類對象
圖形框架: 專用于圖形視圖框架中的圖元
特殊用途: 處理復雜圖形交互場景
同步和異步的網絡連接區別?
- 同步連接
定義: 同步連接是一種阻塞式的網絡連接方式。
特點: 程序在執行同步操作的過程中會被暫停,直到網絡請求完成并返回結果后才繼續執行下一步操作。即當前線程會被阻塞,直到網絡操作完成。- 異步連接
定義: 異步連接是一種非阻塞式的網絡連接方式。
特點:
程序在執行異步操作的時候不會被暫停。當網絡操作返回結果時,系統會發出一個信號通知應用程序,并且在另一個線程中處理網絡數據。
優勢: 異步連接是一種更加高效的網絡連接方式,它可以避免線程的阻塞,提升系統的并發性能。
同步與異步的區別: 兩者唯一的區別在于網絡操作執行的時候,是否會阻塞當前線程。
Qt網絡模塊中有那些類來執行異步操作?
在QT網絡編程當中,直接使用QNetworkAccessManager
和QNetworkReply
來執行異步網絡操作。
QNetworkAccessManager
類
用于管理網絡請求的類,可以發出異步請求和接收服務器響應。提供對cookie的支持和多種網絡功能,可通過Qt文檔搜索獲取詳細信息。
管理機制: 所有請求都會使用內部的QNetworkCookieJar進行cookie管理QNetworkRequest
類
用于向URL發送請求的類,可指定用戶代理字符串、可設置HTTP請求頭、可包含請求數據等參數。QNetworkReply
類
包含發送給QNetworkAccessManager
的數據和首部信息QNetworkCookieJar
類
專門用于管理HTTP cookie的類。可以存儲和讀取cookie,
能夠將cookie與請求一起發送。
Qt如何執行HTTP請求?
- 核心組件
管理組件: 使用QNetworkAccessManager作為HTTP請求的核心管理器,負責協調網絡操作。
請求封裝: QNetworkRequest用于封裝HTTP請求的詳細信息,包括URL和請求頭等。- 執行步驟
(1)實例創建: 首先需要創建QNetworkAccessManager的實例,作為所有網絡請求的入口點。
(2)地址獲取: 通過QUrl類獲取目標URL地址,確保地址格式正確。
(3)請求發送: 使用QNetworkRequest執行GET請求,并通過get()函數發送請求。
(4)循環處理: 通過while循環確保應用程序不會被阻塞,直到網絡操作完成。
(5)數據讀取: 操作完成后通過QNetworkReply實例讀取響應數據。
(6)內存管理: 操作完畢后需要及時清除內存,避免資源泄漏。
什么是Qt Quick?
Qt Quick 是一個用于創建現代用戶界面(UI)的模塊,它是Qt框架的一部分。Qt Quick 的主要目標是提供一種高效、靈活且易于使用的方式來開發動態的、具有豐富動畫效果的界面。
基于QML和JS。能夠創建自定義組件、動畫、交互元素的工具及API。