Qt學習(2)

1.QObject

只有繼承了QObject類的類,才具有信號槽的能力。所以,為了使用信號槽,必須繼承QObject。凡是QObject類(不管是直接子類還是間接子類),都應該在第一行代碼寫上Q_OBJECT。不管是不是使用信號槽,都應該添加這個宏。這個宏的展開將為我們的類提供信號槽機制、國際化機制以及 Qt 提供的不基于 C++ RTTI 的反射能力。因此,如果你覺得你的類不需要使用信號槽,就不添加這個宏,就是錯誤的。其它很多操作都會依賴于這個宏。

示例:

#include <QMainWindow>
#include <QString>
class A:public QObject{
public:A(QObject* parent=NULL):QObject(parent){qInfo()<<this<<"被構造";};~A(){qInfo()<<this<<"被銷毀";};
};
int main(int argc, char* argv[]){A objA;A* pA2=new A(&objA);  //將pA2掛在到objA下A* pA3 = new A(pA2);objA.dumpObjectTree();
}

這樣子就會形成一個樹結構。

QObject:: A
? ? QObject:: pA2
? ? ? ? QObject:: pA3

2.事件與信號

GUI應用程序都由事件驅動,事件主要由應用程序的用戶生成,例如點擊按鈕,控件。或者由其他接觸發生如:Internet連接,窗口管理器或計時器。當調用exec方法時,應用程序進入主循環。主循環將獲取事件并發送到對象。

信號與槽?

信號和槽用于對象之間的通信。

//signal1調用到obj2的slot1
connect(Object1,signal1,Object2,slot1);//signal1調用到obj3的slot1
connect(Object1,signal1,Object3,slot1);

?slot是普通的C++函數,當與之相連的信號發出時將調用。

連接信號和插槽的方式:

1.成員函數指針

connect(senderPtr,&QObject::destoryed,this,&MyObject::objectDestroyed);

2.仿函數或lambda表達式作為slot

connect(sender,&QObject::destoryed,this,[=](){this->m_object.remove(sender);});?

學習示例:

頭文件

#ifndef MYHEAD1_H_
#define MYHEAD1_H_
#include <QCoreApplication>
#include <QDebug>
class Sender : public QObject
{Q_OBJECT
public:explicit Sender(QObject* parent = nullptr);private:int m_age = 10;public:void incAge();
signals:// 信號函數無需定義,只需聲明,并且不能有返回參數,但可以有輸入參數void ageChanged(int value);
};class Receiver : public QObject
{Q_OBJECT
public:explicit Receiver(QObject* parent = nullptr);
public slots://槽函數為普通函數,需要定義,但也不能有返回值void ageChange(int age);
};
#endif  // MYHEAD1_H_

在main函數中調用:

#include "myhead1.h"
int main(int argc, char* argv[])
{Sender senderObj;senderObj.incAge();Receiver recriverObj;//傳遞信號,通過指針的方式傳遞QObject::connect(&senderObj,&Sender::ageChanged,&recriverObj,&Receiver::ageChange);//建立連接后,每次emit發送信號都會傳遞給reciver然后調用ageChangesenderObj.incAge();senderObj.incAge();//斷開連接         QObject::disconnect(&senderObj,&Sender::ageChanged,&recriverObj,&Receiver::ageChange);senderObj.incAge();return 0;
}

當建立連接后,每次emit發送信號后,都會執行相應的槽(slots),而段凱連接后則不會繼續調用槽。

3.鼠標鍵盤響應

? 在MainWindow構造函數中注冊事件,在觸發時讓其發出信號調用對應處理槽.

頭文件

#ifndef MAINWINDOW_H
#define MAINWINDOW_H#include <QMainWindow>QT_END_NAMESPACEclass MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget *parent = nullptr);~MainWindow();// QWidget interface
protected:void keyPressEvent(QKeyEvent *event);void mouseMoveEvent(QMouseEvent *event);
};
#endif // MAINWINDOW_H

實現文件

#include "mainwindow.h"#include <QtWidgets>
MainWindow::MainWindow(QWidget* parent): QMainWindow(parent)
{// 開啟鼠標跟蹤setMouseTracking(true);// 創建一個按鈕對象,入參為按鈕顯示名字和操作對象auto* quitBtn = new QPushButton("Quit", this);// 設置按鈕位置和大小quitBtn->setGeometry(50, 25, 100, 50);// 創建連接,當按鈕點擊事件出發時,調用循環的退出函數connect(quitBtn, &QPushButton::clicked, qApp, &QApplication::quit);
}MainWindow::~MainWindow()
{
}void MainWindow::keyPressEvent(QKeyEvent* event)
{// 如果當前按鍵事件是esc鍵,則退出程序if (event->key() == Qt::Key_Escape)qApp->quit();
}void MainWindow::mouseMoveEvent(QMouseEvent* event)
{// 獲取當前鼠標X坐標int x = event->pos().x();// 獲取y坐標int y = event->pos().y();QString text = "坐標:" + QString::number(x) + "," + QString::number(y);this->statusBar()->showMessage(text);
}

在其中,使用new QPushButton創建了一個按鈕,并且在按鈕中顯示了文字,同時使用按鈕中的方法來指定按鈕的位置和大小(按照x,y軸來判斷位置和創建按鈕大小的).最后通過指針綁定按鈕的點擊事件,當按鈕被按下時觸發QPushButton::clicked,然后調用槽QApplication::quit用來退出程序。

其余的鍵盤檢測按鍵和鼠標位置是通過重寫QMainWindow類中的抽象函數來實現,當在窗口中檢測到時會自動的進行調用.

4.控件與自定義槽

QWidget是用戶界面的原子類。它接收鼠標、鍵盤和來自系統的其他事件,并在屏幕上將它們繪制出來。每個Widget都是矩形的,并按照Z-order(Z軸)進行排序。一個Widget夾在它的Parent和它前面的Widget之間。

沒有嵌入parent widget中的Widget稱為Window。通常情況下,Windows有一個Frame和標題欄(當然也可以通過window flags來取消這些項)。Qt中,QMainWindow和QDialog的多種多樣的子類是最常見的Window類型.


?

這就是一個定義好的QMainWindow,其布局已經是默認規定好的,無法再去增加布局,但是可以創建布局然后替換對應的布局,并放入組件。

頭文件:

#ifndef MAINWINDOW_H_
#define MAINWINDOW_H_
#include <QMainWindow>
class QPushButton;
class QLabel;
class MainWindow : public QMainWindow
{Q_OBJECTpublic:MainWindow(QWidget* parent = nullptr);~MainWindow();private:QPushButton* clickBtn;QLabel* label;// QObject interface
protected:void timerEvent(QTimerEvent *event);public slots:void onClick();void onCheck(int state);
};
#endif  // MAINWINDOW_H

實現文件:

#include "mainwindow.h"#include <QtWidgets>
MainWindow::MainWindow(QWidget* parent): QMainWindow(parent){// 創建一個布局QWidget* myWidget = new QWidget(this);// 替換到中心布局中setCentralWidget(myWidget);// 創建按鈕clickBtn = new QPushButton("點擊", myWidget);// 創建點擊事件QCheckBox* cb = new QCheckBox("Connect", myWidget);// 設置點擊事件默認狀態cb->setCheckState(Qt::Checked);label = new QLabel(QTime::currentTime().toString(), myWidget);//橫向的展示組件QHBoxLayout* hbox = new QHBoxLayout(myWidget);hbox->addWidget(clickBtn);hbox->addWidget(cb);hbox->addWidget(label);startTimer(1000);// 以指針的方式傳入對象和函數connect(clickBtn, &QPushButton::clicked, this, &MainWindow::onClick);connect(cb, &QCheckBox::stateChanged, this, &MainWindow::onCheck);
}MainWindow::~MainWindow()
{
}void MainWindow::timerEvent(QTimerEvent* event)
{// 標識這個形參沒有用到Q_UNUSED(event);label->setText(QTime::currentTime().toString());
}void MainWindow::onClick()
{// 在底部標題欄展示信息statusBar()->showMessage("按鈕被點擊");
}void MainWindow::onCheck(int state)
{statusBar()->showMessage("");// 根據QCheckBox狀態來執行對應函數if (state == Qt::Checked)connect(clickBtn, &QPushButton::clicked, this, &MainWindow::onClick);elsedisconnect(clickBtn, &QPushButton::clicked, this, &MainWindow::onClick);
}

?從這個程序中,我們可以將組件裝入到我們自己創建的widget布局中,然后將該布局設置為中心布局,這樣就可以在中心區域展示組件了,同時創建了自定義的槽,當觸發相應事件的時候調用了自定義槽進行響應。同時也可以根據信號的實時狀態來進行連接和斷開。

?

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

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

相關文章

【Java 進階篇】Jedis 操作 String:Redis中的基礎數據類型

在Redis中&#xff0c;String是最基礎的數據類型之一&#xff0c;而Jedis作為Java開發者與Redis交互的利器&#xff0c;提供了豐富的API來操作String。本文將深入介紹Jedis如何操作Redis中的String類型數據&#xff0c;通過生動的代碼示例和詳細的解釋&#xff0c;讓你輕松掌握…

C# 中using關鍵字的使用

在C#中我們還是很有必要掌握using關鍵字的。 比如這樣&#xff1a; string path “D:\data.txt”; if (!File.Exists(path )) {File.Create(path); File.WriteAllText(path,"OK"); } 首先我創建…

正則表達式(Java)(韓順平筆記)

正則表達式&#xff08;Java&#xff09; 底層實現 package com.hspedu.RegExp;import java.util.regex.Matcher; import java.util.regex.Pattern;public class RegExp00 {public static void main(String[] args) {String content "1998年12月8日&#xff0c;第二代J…

【Promise】某個異步方法執行結束后 在執行下面方法

使用Promise &#xff0c;當 layer.msg(查詢成功) 這個方法執行結束后 &#xff0c;下面代碼才會執行 let thas this async function showMessage() {await new Promise(resolve > layer.msg(查詢成功, resolve));// 這里的代碼將在 layer.msg 執行結束后執行thas.isGuaran…

數字圖像處理(實踐篇)一 將圖像中的指定目標用bBox框起來吧!

目錄 一 實現方法 二 涉及的OpenCV函數 三 代碼 四 效果圖 一 實現方法 ①利用OTSU方法將前景與背景分割。 ②使用連通區域分析可以將具有相同像素值且位置相鄰的前景像素點組成的圖像區域識別。 ③畫bbox。 ④顯示結果。 二 涉及的OpenCV函數 ① OpenCV提供了cv2.th…

如何安裝和配置代理服務器squid?

安裝和配置Squid代理服務器通常需要幾個步驟。以下是在Ubuntu上安裝和配置Squid的簡單步驟&#xff1a; 步驟 1: 安裝Squid 打開終端&#xff0c;并使用以下命令安裝Squid&#xff1a; sudo apt update sudo apt install squid步驟 2: 配置Squid 默認配置文件位于 /etc/squ…

convertRect:toView 方法注意事項

這是在網上找到的一張圖 我們開發中有時候會用到左邊轉換&#xff0c;convertRect:toView 通常情況下&#xff0c;我們回這樣使用 CGRect newRect [a convertRect:originframe toView:c];其中newRect和 originframe的size相同&#xff0c;只改變origin newRect.origin a…

系統優化軟件Bitsum Process Lasso Pro v12.4,供大家學習研究參考

1、自動或手動調整進程優先級;將不需要抑制的進程添加到排除列表; 2、設置動態提升前臺運行的進程/線程的優先級 3、設置進程黑名單,禁止無用進程(機制為啟動即結束,而非攔截其啟動)。 4、優化I/O優先級以及電源模式自動化。 5、ProBalance功能。翻譯成中文是“進程平衡…

STM32入門--CAN

目錄 一、bxCan簡介 二、bxCAN總體描述 2.1概述 2.2CAN框圖 三、bxCA的工作模式 3.1初始化模式 3.2正常模式 3.3睡眠模式&#xff08;低功耗&#xff09; 四、測試模式 4.1靜默模式 4.2環回模式 五、bxCAN功能描述 5.1 發送處理 ?編輯 5.2接收管理 5.2.1 標識符過…

HTTP協議抓包工具Charles 抓包圖文完整教程

Charles是在您自己的計算機上運行的Web代理&#xff08;HTTP代理 / HTTP監視器&#xff09;&#xff0c;您的網絡瀏覽器&#xff08;或任何其他Internet應用程序&#xff09;配置為通過Charles訪問Internet&#xff0c;Charles可以為您記錄并顯示發送和接收的所有數據。 Http抓…

[tsai.shen@mailfence.com].faust勒索病毒數據怎么處理|數據解密恢復

導言&#xff1a; [support2022cock.li].faust、[tsai.shenmailfence.com].faust、[Encrypteddmailfence.com].faust勒索病毒是一種具有惡意目的的勒索軟件&#xff0c;其主要特點包括對受害者文件進行強力加密&#xff0c;然后勒索受害者支付贖金以獲取解密密鑰。攻擊者通常通…

Centos8部署MySQL主從復制報錯問題

問題1.在部署MySQL主從復制時&#xff0c;創建用戶提示ERROR 1819&#xff1a;Your password does not satisfy the current policy requirements。即為當前配置的密碼&#xff0c;不符合策略要求。 問題1解決方式&#xff1a; set global validate_password.policyLOW; \\…

Leetcode—1410.HTML實體解析器【中等】

2023每日刷題&#xff08;三十八&#xff09; Leetcode—1410.HTML實體解析器 算法思想 實現代碼 typedef struct entityChar {char* entity;char rechar; }entity;entity matches[] {{"&quot;", "},{"&apos;", \},{"&amp;"…

NLP中 大語言模型LLM中的思維鏈 Chain-of-Thought(CoT) GoT

文章目錄 介紹思路CoT方法Few-shot CoTCoT Prompt設計CoT投票式CoT-自洽性&#xff08;Self-consistency&#xff09;使用復雜的CoT自動構建CoTCoT中示例順序的影響Zero-shot CoT 零樣本思維鏈 GoT,Graph of Thoughts總結 介紹 在過去幾年的探索中&#xff0c;業界發現了一個現…

C語言之strstr函數的使用和模擬實現

C語言之strstr函數的模擬實現 文章目錄 C語言之strstr函數的模擬實現1. strstr函數的介紹2. strstr函數的使用3. strstr的模擬實現3.1 實現思路3.2 實現代碼 1. strstr函數的介紹 函數聲明如下&#xff1a; char * strstr ( const char * str1, const char * str2 ); strs…

怎樣自動把網頁截圖發到微信群里

現在很多公司都在使用企業微信了&#xff0c;不但方便公司內部交流和客戶交流&#xff0c;還能組建各種小組群&#xff0c;業務群。企業微信群提供一個機器人的功能&#xff0c;方便我們把公司業務信息&#xff0c;或來自外部的信息自動發布到群里。 這里研究一下如何向微信群…

大數據-之LibrA數據庫系統告警處理(ALM-37003 GTM主備不同步或者GTM主備斷連)

告警解釋 當GTM主實例與GTM備實例連接異常或者GTM主實例未處于同步狀態時&#xff0c;產生該告警。 告警屬性 告警ID 告警級別 可自動清除 37003 嚴重 是 告警參數 參數名稱 參數含義 ServiceName 產生告警的服務名稱 RoleName 產生告警的角色名稱 HostName 產…

基于OpenCV+MediaPipe的手勢識別

【精選】【優秀課設】基于OpenCVMediaPipe的手勢識別&#xff08;數字、石頭剪刀布等手勢識別&#xff09;_石頭剪刀布opencv識別代碼_網易獨家音樂人Mike Zhou的博客-CSDN博客 import cv2 import mediapipe as mp import mathdef vector_2d_angle(v1, v2):求解二維向量的角度v…

HIVE SQL 判斷空值函數

目錄 nvl()coalesce() nvl() select nvl(null,2);輸出&#xff1a;2 select nvl(,2);輸出&#xff1a;‘’ coalesce() select coalesce(null,2);輸出&#xff1a;2 select coalesce(,2);輸出&#xff1a;‘’ select coalesce(null,null,2);輸出&#xff1a;2 *coalesc…

Maxwell安裝部署消費到kafka集群

1.上傳安裝包到linux系統上面 2.解壓安裝包到安裝目錄下&#xff0c;并且重命名 [rootVM-4-10-centos package]# tar -zxvf maxwell-1.29.2.tar.gz -C /opt/software/3.配置mysql 增加以下配置 #數據庫id server-id 1 #啟動binlog&#xff0c;該參數的值會作為binlog的文件…