Qt之快捷鍵、事件處理、自定義按鍵——完成記事本項目

快捷鍵

我們電腦中的記事本中還支持快捷鍵,如

“CTRL+O”打開文件、“CTRL+S”保存文件

在Qt中使用QShortcut這個類創建快捷鍵

在.cpp文件的構造函數中創建QShortcut對象,綁定打開文件和保存文件的槽函數

放大縮小字體

還是在.cpp的構造函數中編寫代碼

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setLayout(ui->verticalLayout);ui->widget_2->setLayout(ui->horizontalLayout_2);connect(ui->comboBox,SIGNAL(currentIndexChanged(int)),this,SLOT(oncurrentIndex(int)));connect(ui->textEdit,SIGNAL(cursorPositionChanged()),this,SLOT(oncursorPosition()));QShortcut *shortcutOpen=new QShortcut(QKeySequence(tr("Ctrl+O","File|Open")),this);        //添加快捷鍵QShortcut *shortcutSave=new QShortcut(QKeySequence(tr("Ctrl+S","File|Save")),this);connect(shortcutOpen,&QShortcut::activated,[=](){on_Bopen_clicked();});                    //綁定信號與槽(指針)connect(shortcutSave,&QShortcut::activated,[=](){on_Bsave_clicked();});QShortcut *shortcutZoomBig=new QShortcut(QKeySequence(tr("Ctrl+Shift+=","File|Save")),this);   //ctrl、shift、+號同時按下(+與=在同一個位置)QShortcut *shortcutZoomSmall=new QShortcut(QKeySequence(tr("Ctrl+Shift+-","File|Save")),this); connect(shortcutZoomBig,&QShortcut::activated,[=](){QFont font = ui->textEdit->font();            //獲取當前字體信息int fontSize = font.pointSize();              //獲取當前字體大小if(fontSize==-1) return;int newfontSize=fontSize+1;                   //改變字體大小font.setPointSize(newfontSize);               //設置新字體大小ui->textEdit->setFont(font);});  connect(shortcutZoomSmall,&QShortcut::activated,[=](){QFont font = ui->textEdit->font();            //獲取當前字體信息int fontSize = font.pointSize();              //獲取當前字體大小if(fontSize==-1) return;int newfontSize=fontSize-1;                   //改變字體大小font.setPointSize(newfontSize);               //設置新字體大小ui->textEdit->setFont(font);});   
}

事件處理

事件是 Qt 程序與用戶(或操作系統)交互的基本單元:用戶按下鼠標、鍵盤輸入、窗口被遮擋或暴露、定時器到期……都會產生一個 QEvent 對象。

過去我們常用“信號-槽”機制來處理用戶動作,但信號-槽只能覆蓋 Qt 已定義好的“高層語義”,遇到“關閉窗口時詢問是否保存”“拖拽窗口時限制范圍”這類底層或組合行為,就必須介入真正的事件處理流程。

在 Qt 中,事件處理分為四個連貫的步驟:

  1. 事件派發(dispatch):QApplication::notify() 把事件發給目標對象;

  2. 事件過濾(filter):沿途的所有 QObject::eventFilter() 都有機會截斷或修改事件;

  3. 事件分發(delivery):目標對象內部的 QWidget::event() 根據事件類型再細分;

  4. 事件處理(handle):具體虛函數如 mousePressEvent()closeEvent() 最終被執行。

在Qwidget中的保護成員中,還有如下這些事件處理函數,如closeEvent()可以關閉窗口,我們重寫事件處理函數也可以在一定程度上處理事件。

事件重寫

我們再來添加一個關閉窗口時的彈窗詢問

打開.h文件,聲明重寫closeEvent()事件處理函數(widget繼承于Qwidget)

同時按下“ALT+ENTER”,在.cpp文件中添加實現

void Widget::closeEvent(QCloseEvent *event)           //記得添加頭文件
{int ret=QMessageBox::warning(this,tr("My Application"),tr("close the window.\n""Do you want to close the window?"),QMessageBox::Yes|QMessageBox::No);      //彈窗switch (ret) {case QMessageBox::Yes:event->accept();        //QCloseEvent繼承于QEvent,accept接受事件,ignore忽略 break;case QMessageBox::No:event->ignore();break;}}

自定義按鍵

按鍵個性化設置

新建一個項目(同前),然后自定義一個按鈕

右鍵項目,點擊“Add New”

點擊“C++ Class”,點擊“choose”

繼承于QWidget,點擊“下一步”,點擊“完成”

需要在.h文件中聲明的成員如下

再次右鍵項目名稱,點擊“Add New”,添加一個Qt的資源文件

點擊“Add Files”,選擇3張圖片樣式添加(在項目文件下添加),“CTRL+S”保存

在.cpp文件中實現重寫邏輯

右鍵復制圖片文件地址

#include "mybutton.h"#include <QPainter>MyButton::MyButton(QWidget *parent) : QWidget(parent)
{pic.load(":/p1.png");   //加載圖片(初始圖片)setFixedSize(pic.size());  //設置按鍵大小為圖片大小update();                  //刷新,觸發paintEvent()
}void MyButton::mousePressEvent(QMouseEvent *event)    
{pic.load(":/p3.png");update();
}void MyButton::leaveEvent(QEvent *event)
{pic.load(":/p1.png");update();    
}void MyButton::enterEvent(QEvent *event)
{pic.load(":/p2.png");update();    
}void MyButton::paintEvent(QPaintEvent *event)
{QPainter painter(this);                    //繪畫師painter.drawPixmap(rect(),pic);            //繪制圖像(矩形,位圖)}

打開.ui文件,托入一個widget控件,右鍵,點擊“提升為”

輸入新按鈕的類的名稱,點擊“添加”

點擊運行文件,按鈕圖標能正常轉換

這樣自定義后按鍵的形狀就能隨自己設計,更好看一些(可以用圖片等)

自定義按鍵的信號與槽

在"button.h"文件中聲明點擊信號

在widget.cpp中引入button的頭文件

connect綁定信號與槽

并在button.cpp文件,在鼠標信號點擊處,發送點擊信號

點擊“打開”按鈕后,能正常發射信號

事件重寫實現滾輪放大縮小字體

標準的QTextEdit控件并不支持“CTAL+鼠標滾輪”,所以我們要自定義一個MyTextEdit出來,再將notebook原來的textEdit提升為我們自定義的textEdit類(原代碼.c文件不用修改,都是繼承于QtextEdit實現)

右鍵項目名稱,新建一個類文件

標注父控件

在我們的MyTextEdit構造時還需標注父控件,使MyTextEdit與ui中的TextEdit聯系起來(ui中所有控件都有QWidget這個父親)

“ALT+ENTER”添加構造函數的實現(把原來的刪掉)

MyTextEdit::MyTextEdit(QWidget *parent):QTextEdit(parent)    //調用QtextEdit的構造函數實現
{}

再在.h文件中聲明要實現的功能

#ifndef MYTEXTEDIT_H
#define MYTEXTEDIT_H#include <QTextEdit>class MyTextEdit : public QTextEdit
{
public:MyTextEdit(QWidget *parent);protected:void wheelEvent(QWheelEvent *e) override;              //鼠標滾輪事件void keyPressEvent(QKeyEvent *e) override;             //按鍵按下事件void keyReleaseEvent(QKeyEvent *e) override;           //按鍵松開事件
};#endif // MYTEXTEDIT_H

提升TextEdit

在ui中右鍵TextEdit,“提升為”

然后右邊可以看到已經提升過來了

代碼實現

放大和縮小字體的代碼與之前快捷鍵實現重復了,所以直接把之前那段代碼用函數封裝調用就好了

widget.h添加聲明

widget.cpp添加實現

使用事件函數基本的使用,我們已經能寫出大致框架,但我們要實現的應該是“CTRL+滾輪”實現,但滾輪能夠上下滑動

我們只要添加一個bool型的變量,使同時操作時再調用函數就可以了

以及除了同時按下,正常操作的反應要繼承下來

#include "mytextedit.h"#include <QCloseEvent>MyTextEdit::MyTextEdit(QWidget *parent):QTextEdit(parent)    //調用QtextEdit的構造函數實現
{}void MyTextEdit::wheelEvent(QWheelEvent *e)
{if(ctrlKeyPressed==1){if(e->angleDelta().y()>0){                           //上滑縮小zoomIn();}else if(e->angleDelta().y()<0){zoomOut();}e->accept();                                         //處理完畢}else{QTextEdit::wheelEvent(e);                             //正常執行QTextEdit的滾輪事件}
}void MyTextEdit::keyPressEvent(QKeyEvent *e)
{if(e->key()==Qt::Key_Control){                          //Ctrl按下ctrlKeyPressed=1;}QTextEdit::keyPressEvent(e);                            //按鍵按下執行
}void MyTextEdit::keyReleaseEvent(QKeyEvent *e)
{if(e->key()==Qt::Key_Control){                          //Ctrl釋放ctrlKeyPressed=0;}QTextEdit::keyReleaseEvent(e);
}

事件過濾器

對于Qt事件,我們主要把中重點放在事件處理和事件過濾

事件過濾器適用于:當你不想在修改子代碼的情況下改變事件的行為(如上面的情況不添加新的類)。可在事件到達目標對象之前進行攔截和處理

先在.h文件添加聲明

安裝事件過濾器

在事件過濾器中,我們既要檢測滾輪,又要檢測“Ctrl”是否被按下。若單使用QEvent事件,檢測滾輪會調用一次,檢測ctrl按下又會調用一次。則兩個事件不能同時被檢測,所以我們換種方式檢測滾輪。

bool Widget::eventFilter(QObject *watched, QEvent *event)
{if(event->type()==QEvent::Wheel){             //事件是滾輪事件if(QGuiApplication::keyboardModifiers()==Qt::ControlModifier){    //ctrl被按下QWheelEvent *weelEvent=dynamic_cast<QWheelEvent*>(event);                   //轉換類型if(weelEvent->angleDelta().y()>0){zoomIn();}else{zoomOut();}return true;                           //事件已執行}return false;                              //若ctrl沒被按下,事件繼續傳遞給目標對象}
}

至此,我們的記事本項目簡單完成!

下圖為up主老陳的總結

?

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

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

相關文章

Open cascade中如何使用BRepAlgoAPI_Splitter分割一個Face

理論介紹 在OpenCASCADE幾何建模內核中&#xff0c;BRepAlgoAPI_Splitter是一個強大的工具&#xff0c;用于將一個形狀&#xff08;Shape&#xff09;用另一個形狀&#xff08;Tool&#xff09;進行分割。這種操作在CAD建模中非常常見&#xff0c;比如用平面切割實體、用曲線分…

【醫療 AI】Baichuan-M2 醫療大模型:技術解讀與使用方法

【醫療 AI】Baichuan-M2 醫療大模型&#xff1a;技術解讀與使用方法1. Baichuan-M2 醫療大模型簡介1.1 基本信息1.2 下載地址1.3 技術特點2. Baichuan-M2 模型技術報告2.1 摘要2.2 醫學性能評估2.2.1 HealthBench基準2.2.2 中國醫療場景對比評估2.3 系統架構2.3.1 驗證器系統2.…

unity pcd 二進制版 簡單顯示文件對象(單色)

unity Point Cloud Viewer and Tool 那個插件不支持pcd二進制&#xff0c;而且網上到處都是AI 我恨這種AI濫用&#xff0c;提供不了一點價值 好了&#xff0c;言歸正傳 可以在Point Cloud Viewer and Tool這個插件報錯地方轉用這個代碼&#xff0c;具體咋結合請自行研究。 …

強大的開源文檔問答工具-Kotaemon

Kotaemon 是一個基于 RAG&#xff08;Retrieval-Augmented Generation&#xff09;架構的開源文檔問答工具&#xff0c;為用戶提供與文檔對話的智能交互體驗。該項目同時服務于終端用戶和開發者&#xff0c;具有高度的可擴展性和定制化能力。技術棧分析核心技術棧后端框架Pytho…

區塊鏈:搭建簡單Fabric網絡并調用智能合約

使用docker服務搭建Hyperledger/fabric網絡的詳細教程&#xff0c;實現構建多節點的簡單聯盟鏈&#xff0c;并編寫、調用智能合約實現投票業務。 目錄 背景知識 Hyperledger Fabric 基本組件 交易(Transaction) 智能合約 實驗目的 實驗環境 基礎依賴 安裝Golang 安裝do…

Web前端面試題(2)

Web前端面試題(附答案及解析)&#xff08;2025.9月最新版&#xff09;-CSDN博客 1.link 與 import 的區別和用法 主要區別 特性<link>import語法類型HTML標簽CSS規則加載方式并行加載&#xff08;與其他資源同時加載&#xff09;串行加載&#xff08;必須等待主CSS文件…

Paxos協議

目錄 Paxos 是什么&#xff08;What&#xff09; Paxos 的目的&#xff08;Why&#xff09; 角色與職責&#xff08;Who&#xff09; 基本流程&#xff08;How&#xff09; 常見問題與對策 什么是多數派&#xff08;Quorum&#xff09; Paxos vs Raft 異同點 Paxos 是什…

第十二篇:Qcom Camx打印實時幀率 FPS

一、第一種方式(有些低平臺可能沒有) adb shell setprop persist.vendor.camera.enableFPSLog TRUE adb shell setprop persist.vendor.camera.systemLogEnable TRUE adb shell setprop vendor.debug.camera.overrideLogLevels 0xff chi-cdk/core/chiframework/chxextensi…

TRAE通用6A規則+敏捷開發5S規則

網上研究別人的一些規則,也搞一份給大家 6A工作流項目規則 身份定義 你是一位資深的軟件架構師和工程師,具備豐富的項目經驗和系統思維能力。你的核心優勢在于: 上下文工程專家:構建完整的任務上下文,而非簡單的提示響應 規范驅動思維:將模糊需求轉化為精確、可執行的規…

【Nginx開荒攻略】Nginx主配置文件結構與核心模塊詳解:從0到1掌握nginx.conf:

目錄 引言 1 nginx.conf的整體結構 2 main全局塊詳解 2.1 核心指令解析 2.1.1 user&#xff1a;運行用戶 2.1.2 worker_processes&#xff1a;工作進程數 2.1.3 pid&#xff1a;PID文件路徑 2.1.4 worker_rlimit_nofile&#xff1a;文件描述符限制 2.2 main塊配置示例…

【前端教程】從基礎到優化:一個登錄頁面的完善過程

最近做了一個簡單的登錄頁面,主要練習了文本框的onfocus與onblur事件的使用。雖然功能實現了,但仔細想想還有不少可以改進的地方。今天就來分享一下這個登錄頁面的開發過程和優化思路。 初始實現與解析 先來看一下最初的實現代碼: <!DOCTYPE html> <html> &l…

獨家 | 抖音生活服務調整:涂晴接管市場和達人運營,旭凱擔任北部大區負責人

文/刀客doc(頭條精選作者)刀客doc獨家獲悉&#xff0c;9月8日抖音生活服務完成新一輪組織調整&#xff0c;并已在內部all hands完成官宣。此次調整主要涉及北部大區、達人運營與市場部三大條線的人事輪換與匯報關系變更。核心變動如下&#xff1a;涂晴&#xff0c;原抖音生活服…

class_9:java 抽象類和接口

抽象類 需要用abstract 修飾類和接口abstract class Person{String address;String name;abstract public void eat();abstract public void drink();public void printInfo(){System.out.println("name " name);}} class Student extends Person{public void eat()…

【C++】隊列queue的使用

語法 在 C 中&#xff0c;隊列的語法如下&#xff1a; #include <queue>// 聲明隊列 std::queue<Type> q;這里 Type 是隊列中存儲元素的數據類型。 常用操作 隊列提供了以下常用操作&#xff1a; empty(): 檢查隊列是否為空。 size(): 返回隊列中的元素數量。 fron…

HTTP 協議的基本格式

目錄 &#xff08;一&#xff09;HTTP是什么 &#xff08;二&#xff09;報文格式 &#xff08;1&#xff09;請求 ①首行 1.URL 2.方法&#xff08;method&#xff09; Ⅰ.GET Ⅱ.POST Ⅲ.PUT Ⅳ.DELETE 3.版本號 ②請求頭&#xff08;header&#xff09; 1.鍵值對…

計算機網絡的基本概念-2

1、數據交換技術&#xff1a;電路交換、報文交換與分組交換網絡核心部分的關鍵設備是路由器&#xff0c;其工作方式是分組交換。要理解分組交換&#xff0c;必須先了解其前兩種技術。1. 電路交換 (Circuit Switching)核心思想&#xff1a;通信前必須預先建立一條專用的物理通路…

車載網絡技術--SOME_IP協議詳解

文章目錄前言SOME/IP概念SOME/IP協議格式SOME/IP功能介紹序列化序列化規則發布和訂閱服務發現&#xff08;SOME/IP-SD&#xff09;SOME/IP-TP協議使用場景SOME/IP-TP協議參考文章&#xff1a;前言 本文介紹了SOME/IP協議的具體內容&#xff0c;包括報文格式&#xff0c;協議選…

JVM 核心知識全解析:從類加載到垃圾回收的深度認知

什么是JVM&#xff1f; JVM全稱&#xff08;Java Virtual Machine&#xff09;&#xff0c;中譯為&#xff1a;Java虛擬機 本質&#xff1a;是一個運行在計算機上的程序 職責&#xff1a;運行Java字節碼文件&#xff08;因為計算機只能認識機器碼文件&#xff0c;所以需要JVM將…

Keepalived 負載均衡

Keepalived 負載均衡 Keepalived 可以與 LVS&#xff08;Linux Virtual Server&#xff09;結合&#xff0c;提供強大的四層負載均衡功能。它通過 IPVS&#xff08;IP Virtual Server&#xff09;內核模塊實現高性能的負載分發。 核心組件 Virtual Server&#xff1a;虛擬服務器…

拷打DeepSeek實現自動生成差分電荷計算文件和后處理

差分電荷&#xff08;charge density difference&#xff09;是材料模擬中分析電子結構變化的直觀工具。 它把成鍵后的真實電荷密度減去成鍵前各碎片疊加的電荷密度&#xff0c;得到一張“電子遷移地圖” 于是可以一眼看出化學鍵形成時電子從哪里來到哪里去&#xff0c;表面吸…