【二十七】【QT开发应用】VS如何复制项目,QT无边窗窗口Pro版本,信号与信号槽的应用,背景图片自适应控件大小

VS复制项目

在使用VS的过程中,有的时候我们需要复制我们已经存在的项目.

在这里插入图片描述
我们可以先创建一个新的项目.
在这里插入图片描述

接着把需要复制的项目的文件复制粘贴到新的项目文件夹中.

在这里插入图片描述
不要忘记添加现有项目.

CFrameLessWidgetBase.h

#pragma once
#include <QWidget>
class CFrameLessWidgetBase : public QWidget{QOBJECT_Hpublic:CFrameLessWidgetBase(QWidget* p = nullptr);~CFrameLessWidgetBase();
private:protected:bool nativeEvent(const QByteArray& eventType, void* message, qintptr* result) override;private:int m_nBorderWidth = 10;
};

CFrameLessWidgetBase.cpp

#include "CFrameLessWidgetBase.h"
#include <qt_windows.h>
#include <windows.h>
#include <windowsx.h>#pragma comment(lib, "user32.lib")
#pragma comment(lib,"dwmapi.lib")CFrameLessWidgetBase::CFrameLessWidgetBase(QWidget* p):QWidget(p) {this->setWindowFlags(Qt::FramelessWindowHint);
}
CFrameLessWidgetBase:: ~CFrameLessWidgetBase() {};bool CFrameLessWidgetBase::nativeEvent(const QByteArray& eventType, void* message, qintptr* result) {MSG* param = static_cast<MSG*>(message);switch (param->message) {case WM_NCHITTEST:{/*int nX = GET_X_LPARAM(param->lParam) - this->geometry().x();int nY = GET_Y_LPARAM(param->lParam) - this->geometry().y();*/QPoint globalPos = QCursor::pos(); // 获取鼠标的全局坐标QPoint localPos = this->mapFromGlobal(globalPos); // 转换为窗口坐标int nX = localPos.x(); // 现在的 nX 应该是相对于窗口的坐标int nY = localPos.y();//if (childAt(nX, nY) != nullptr)//	return QWidget::nativeEvent(eventType, message, result);if (nX > m_nBorderWidth && nX < this->width() - m_nBorderWidth &&nY > m_nBorderWidth && nY < this->height() - m_nBorderWidth) {if (childAt(nX, nY) != nullptr)return QWidget::nativeEvent(eventType, message, result);}if ((nX > 0) && (nX < m_nBorderWidth))*result = HTLEFT;if ((nX > this->width() - m_nBorderWidth) && (nX < this->width()))*result = HTRIGHT;if ((nY > 0) && (nY < m_nBorderWidth))*result = HTTOP;if ((nY > this->height() - m_nBorderWidth) && (nY < this->height()))*result = HTBOTTOM;if ((nX > 0) && (nX < m_nBorderWidth) && (nY > 0)&& (nY < m_nBorderWidth))*result = HTTOPLEFT;if ((nX > this->width() - m_nBorderWidth) && (nX < this->width())&& (nY > 0) && (nY < m_nBorderWidth))*result = HTTOPRIGHT;if ((nX > 0) && (nX < m_nBorderWidth)&& (nY > this->height() - m_nBorderWidth) && (nY < this->height()))*result = HTBOTTOMLEFT;if ((nX > this->width() - m_nBorderWidth) && (nX < this->width())&& (nY > this->height() - m_nBorderWidth) && (nY < this->height()))*result = HTBOTTOMRIGHT;return true;}}return false;
}

将相关的代码放到一个类里面.
在这里插入图片描述
在这里插入图片描述
将主widget继承这个类.

CTitleBar.h

#pragma once
#include <QWidget>
#include <QLabel>
#include <QPushButton>
class CTitleBar : public QWidget 
{Q_OBJECTpublic:CTitleBar(QWidget* p = nullptr);~CTitleBar();private:void initUI();private:void mousePressEvent(QMouseEvent* event) override;void mouseDoubleClickEvent(QMouseEvent* event) override;private slots:void onClicked();signals:void sig_close();private:QLabel* Label_mpLogo;QLabel* Label_mpTitleText;QPushButton* Btn_mpSet;QPushButton* Btn_mpMin;QPushButton* Btn_mpMax;QPushButton* Btn_mpClose;};

void mouseDoubleClickEvent(QMouseEvent* event) override;鼠标双击事件.
private slots: void onClicked();自定义槽函数.
signals: void sig_close();自定义信号.

CTitleBar.cpp

#include "CTitleBar.h"
#include <QHBoxLayout>
#include <QVBoxLayout>
#include <qt_windows.h>
#include <QPushButton>CTitleBar::CTitleBar(QWidget* p):QWidget(p) {initUI();
}CTitleBar::~CTitleBar() {}void CTitleBar::initUI() {setAttribute(Qt::WA_StyledBackground);this->setStyleSheet("background-color:rgb(156,156,156)");this->setFixedHeight(32);Label_mpLogo = new QLabel(this);Label_mpTitleText = new QLabel(this);Btn_mpSet = new QPushButton(this);Btn_mpMin = new QPushButton(this);Btn_mpMax = new QPushButton(this);Btn_mpClose = new QPushButton(this);Label_mpLogo->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/title_icon.png);");Btn_mpSet->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/set.svg);");Btn_mpMin->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/min.svg);");Btn_mpMax->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/normal.svg);");Btn_mpClose->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/close.svg);");Label_mpLogo->setFixedSize(24, 24);Label_mpTitleText->setText("我是标题");Label_mpTitleText->setFixedWidth(120);Btn_mpSet->setFixedSize(24, 24);Btn_mpMin->setFixedSize(24, 24);Btn_mpMax->setFixedSize(24, 24);Btn_mpClose->setFixedSize(24, 24);QHBoxLayout* Layout_pHTitle = new QHBoxLayout(this);Layout_pHTitle->addWidget(Label_mpLogo);Layout_pHTitle->addWidget(Label_mpTitleText);Layout_pHTitle->addStretch();Layout_pHTitle->addWidget(Btn_mpSet);Layout_pHTitle->addWidget(Btn_mpMin);Layout_pHTitle->addWidget(Btn_mpMax);Layout_pHTitle->addWidget(Btn_mpClose);Layout_pHTitle->setContentsMargins(5, 5, 5, 5);connect(Btn_mpSet, &QPushButton::clicked, this, &CTitleBar::onClicked);connect(Btn_mpMin, &QPushButton::clicked, this, &CTitleBar::onClicked);connect(Btn_mpMax, &QPushButton::clicked, this, &CTitleBar::onClicked);connect(Btn_mpClose, &QPushButton::clicked, this, &CTitleBar::onClicked);
}void CTitleBar::mousePressEvent(QMouseEvent* event) {//实现窗口可拖拽if (ReleaseCapture()) {QWidget* pWindow = this->window();if (pWindow->isTopLevel()) {SendMessage(HWND(pWindow->winId()), WM_SYSCOMMAND, SC_MOVE + HTCAPTION, 0);}}
}void CTitleBar::mouseDoubleClickEvent(QMouseEvent* event) {Btn_mpMax->click();
}void CTitleBar::onClicked() {QPushButton* btn_ptemp = qobject_cast<QPushButton*>(sender());QWidget* widget_window = this->window();if (btn_ptemp == Btn_mpMin) {widget_window->showMinimized();} else if (btn_ptemp == Btn_mpMax) {if (widget_window->isMaximized()) {widget_window->showNormal();} else {widget_window->showMaximized();}} else if (btn_ptemp == Btn_mpClose) {emit sig_close();}}

图片自适应控件

	Label_mpLogo->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/title_icon.png);");Btn_mpSet->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/set.svg);");Btn_mpMin->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/min.svg);");Btn_mpMax->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/normal.svg);");Btn_mpClose->setStyleSheet("border-image:url(:/MainWidget/resources/titlebar/close.svg);");

使用border-image:这个属性可以让你设置控件的边框图像,并且可以在控件大小变化时保持图像的比例和位置。

信号槽连接

	connect(Btn_mpSet, &QPushButton::clicked, this, &CTitleBar::onClicked);connect(Btn_mpMin, &QPushButton::clicked, this, &CTitleBar::onClicked);connect(Btn_mpMax, &QPushButton::clicked, this, &CTitleBar::onClicked);connect(Btn_mpClose, &QPushButton::clicked, this, &CTitleBar::onClicked);

这四个按钮的点击信号全部链接相同的函数.在这一个函数中我们需要怎样区分信号的来源?

区分信号来源

void CTitleBar::onClicked() {QPushButton* btn_ptemp = qobject_cast<QPushButton*>(sender());QWidget* widget_window = this->window();if (btn_ptemp == Btn_mpMin) {widget_window->showMinimized();} else if (btn_ptemp == Btn_mpMax) {if (widget_window->isMaximized()) {widget_window->showNormal();} else {widget_window->showMaximized();}} else if (btn_ptemp == Btn_mpClose) {emit sig_close();}}

函数结构

void CTitleBar::onClicked() {QPushButton* btn_ptemp = qobject_cast<QPushButton*>(sender());
  • void CTitleBar::onClicked():这是 CTitleBar 类中的槽函数,处理按钮点击事件。
  • QPushButton* btn_ptemp = qobject_cast<QPushButton*>(sender());:使用 sender() 获取发送信号的对象,并尝试将其转换为 QPushButton* 类型。qobject_cast 安全地进行类型转换,如果转换失败,则返回 nullptr

获取窗口

QWidget* widget_window = this->window();
  • QWidget* widget_window = this->window();:获取当前标题栏所属的窗口(父窗口)指针。

按钮点击处理

if (btn_ptemp == Btn_mpMin) {widget_window->showMinimized();
} else if (btn_ptemp == Btn_mpMax) {if (widget_window->isMaximized()) {widget_window->showNormal();} else {widget_window->showMaximized();}
} else if (btn_ptemp == Btn_mpClose) {emit sig_close();
}
  1. 最小化按钮

    • if (btn_ptemp == Btn_mpMin):检查点击的按钮是否是最小化按钮。
    • widget_window->showMinimized();:调用窗口的 showMinimized() 方法,将窗口最小化。
  2. 最大化按钮

    • else if (btn_ptemp == Btn_mpMax):检查是否是最大化按钮。
    • if (widget_window->isMaximized()):判断窗口是否已经最大化。
      • widget_window->showNormal();:如果是最大化,则恢复窗口到正常状态。
      • widget_window->showMaximized();:如果不是,则将窗口最大化。
  3. 关闭按钮

    • else if (btn_ptemp == Btn_mpClose):检查是否是关闭按钮。
    • emit sig_close();:发出 sig_close 信号,通常用于通知其他部分关闭窗口。

MainWidget.cpp

#include "MainWidget.h"
#include "QVBoxLayout"
#include <qt_windows.h>
#include <windows.h>
#include <windowsx.h>
#include <QMessageBox>#pragma comment(lib, "user32.lib")
#pragma comment(lib,"dwmapi.lib")MainWidget::MainWidget(QWidget* parent): CFrameLessWidgetBase(parent) {//this->setWindowFlags(Qt::FramelessWindowHint |Qt::WindowMinMaxButtonsHint );this->setWindowFlags(Qt::FramelessWindowHint);initUI();
}MainWidget::~MainWidget() {}void MainWidget::initUI() {CTitleBar_mp = new CTitleBar(this);QWidget* Widget_Main = new QWidget(this);Widget_Main->setMinimumSize(600, 400);QVBoxLayout* Layout_pVMain = new QVBoxLayout(this);Layout_pVMain->addWidget(CTitleBar_mp);Layout_pVMain->addWidget(Widget_Main);Layout_pVMain->setContentsMargins(0, 0, 0, 0);setLayout(Layout_pVMain);connect(CTitleBar_mp, &CTitleBar::sig_close, this, &MainWidget::on_closeSlot);}void MainWidget::on_closeSlot() {close();
}

连接自定义信号和槽函数

connect(CTitleBar_mp, &CTitleBar::sig_close, this, &MainWidget::on_closeSlot);

信号和槽连接

connect(CTitleBar_mp, &CTitleBar::sig_close, this, &MainWidget::on_closeSlot);
  • connect(...):这是 Qt 的信号和槽机制,用于将一个对象的信号与另一个对象的槽连接起来。
  • CTitleBar_mp:这是 CTitleBar 类的一个实例,通常是一个自定义的标题栏控件。
  • &CTitleBar::sig_close:这是 CTitleBar 类中定义的信号。当这个信号被发出时,连接的槽会被调用。
  • this:指向当前对象(MainWidget 的实例)。
  • &MainWidget::on_closeSlot:这是 MainWidget 类中的槽函数。当 sig_close 信号被发出时,on_closeSlot() 函数将被调用。

槽函数实现

void MainWidget::on_closeSlot() {close();
}
  • close();:调用 close() 方法,该方法会关闭当前窗口(MainWidget 实例)。

总结

当用户在 CTitleBar 中点击关闭按钮时,会发出 sig_close 信号,随后 MainWidgeton_closeSlot 槽函数被调用,执行 close() 方法,从而关闭主窗口。这是 Qt 信号和槽机制的一种常见用法,用于实现不同组件之间的通信。

结尾

最后,感谢您阅读我的文章,希望这些内容能够对您有所启发和帮助。如果您有任何问题或想要分享您的观点,请随时在评论区留言。
同时,不要忘记订阅我的博客以获取更多有趣的内容。在未来的文章中,我将继续探讨这个话题的不同方面,为您呈现更多深度和见解。
谢谢您的支持,期待与您在下一篇文章中再次相遇!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/438482.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统架构设计师④:计算机网络

系统架构设计师④&#xff1a;计算机网络 TCP/IP协议族 模型如下&#xff1a; 常用的协议及端口号&#xff1a; 各个协议能力介绍&#xff1a; TCP与UDP的对比&#xff1a; DNS协议 DSN&#xff1a;域名系统( Domain Name System) 支持两种查询方式 &#xff1a; ①递…

elasticsearch设置账号和密码

1、es安装&#xff0c;挂载路径根据实际情况修改 docker run -d --restart always \ --name es \ -e "ES_JAVA_OPTS-Xms512m -Xmx512m" \ -e "discovery.typesingle-node" \ -e "TZAsia/Shanghai" \ -v /mnt/data/efk/es/data:/usr/share/elast…

uniapp使用字体图标 ttf svg作为选项图标,还支持变色变图按

在staic目录下有一些ttf文件&#xff0c;如uni.ttf&#xff0c;iconfont.ttf 这些文件中保存这字体svg的源码们&#xff0c;我们也可以在网上找其他的。这些就是我们要显示的突图标的 显示来源。这样不用使用png图标&#xff0c;选中不选中还得用两个图片 我的具体使用如下 &q…

新手教学系列——用 VSCode 实现高效远程开发

随着软件开发环境日益复杂,远程开发已成为许多开发者的日常工作方式。尤其当项目需要直接在服务器上运行或本地计算资源有限时,能够使用一款便捷、强大的工具至关重要。在众多 IDE 中,VSCode 因其轻量、灵活且支持丰富插件,成为远程开发的理想选择。本文将详细介绍如何通过…

PasteForm最佳CRUD实践,实际案例PasteTemplate详解之3000问(三)

作为“贴代码”力推的一个CRUD实践项目PasteTemplate,在对现有的3个项目进行实战后效果非常舒服&#xff01;下面就针对PasteForm为啥我愿称为最佳CRUD做一些回答: 哪里可以下载这个PasteForm的项目案例 目前“贴代码”对外使用PasteForm的项目有"贴Builder(PasteSpide…

[云服务器18] 搭建AIGC APP?AI绘图不神秘!

好的这是我的第18篇blog了&#xff01;开心max&#xff01; 那么&#xff0c;这次我们来做些什么呢……&#xff08;思考中&#xff09; 此时的我拿起了手机&#xff0c;打开了某APP&#xff0c;然后赫然出现的广告&#xff1a; 现在是AI的时代&#xff0c;为什么不来学习AIGC…

《开题报告》基于SSM框架的电影评论网站的设计与实现源码++学习文档+答辩讲解视频

开题报告 研究背景 随着互联网技术的飞速发展&#xff0c;网络已成为人们获取信息、交流思想、分享体验的重要平台。在电影产业蓬勃发展的今天&#xff0c;观众对于电影的选择不再仅仅依赖于传统的宣传渠道&#xff0c;而是更加倾向于通过在线平台了解影片内容、观看预告片、…

Mybatis的基本使用

什么是Mybatis&#xff1f; Mybatis是一个简化JDBC的持久层框架&#xff0c;MyBatis是一个半自动化框架&#xff0c;是因为它在SQL执行过程中只提供了基本的SQL执行功能&#xff0c;而没有像Hibernate那样将所有的ORM操作都自动化了。在MyBatis中&#xff0c;需要手动编写SQL语…

第十三章 集合

一、集合的概念 集合&#xff1a;将若干用途、性质相同或相近的“数据”组合而成的一个整体 Java集合中只能保存引用类型的数据&#xff0c;不能保存基本类型数据 数组的缺点&#xff1a;长度不可变 Java中常用集合&#xff1a; 1.Set(集):集合中的对象不按特定方式排序&a…

工具模块及项目整体模块框架

文章目录 工具模块logger.hpphelper.hppthreadpool.hpp 核心概念核心API交换机类型持久化⽹络通信消息应答持久化数据管理中心模块虚拟机管理模块交换路由模块消费者管理模块信道管理模块连接管理模块Broker服务器模块消费者管理信道请求模块通信连接模块项⽬模块关系图 工具模…

ScrapeGraphAI 大模型增强的网络爬虫

在数据驱动的动态领域&#xff0c;从在线资源中提取有价值的见解至关重要。从市场分析到学术研究&#xff0c;对特定数据的需求推动了对强大的网络抓取工具的需求。 NSDT工具推荐&#xff1a; Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线…

电脑出现msvcp140.dll丢失的解决方法,总结6种解决方法

在计算机使用过程中&#xff0c;我们常常会遇到一些错误提示&#xff0c;其中最常见的就是“msvcp140.dll丢失”的错误。这个错误提示通常出现在运行某个程序时&#xff0c;它意味着计算机无法找到所需的msvcp140.dll文件。那么&#xff0c;msvcp140.dll丢失是怎么回事呢&#…

69 BERT预训练_by《李沐:动手学深度学习v2》pytorch版

系列文章目录 文章目录 系列文章目录NLP里的迁移学习Bert的动机Bert架构对输入的修改五、预训练任务1、2、3、 六、1、2、3、 七、1、2、3、 八、1、2、3、 NLP里的迁移学习 之前是使用预训练好的模型来抽取词、句子的特征&#xff0c;例如 word2vec 或语言模型这种非深度学习…

银河麒麟V10如何关闭定期锁屏功能?

银河麒麟V10如何关闭定期锁屏功能? 1. 打开终端2. 执行命令3. 验证设置 &#x1f496;The Begin&#x1f496;点点关注&#xff0c;收藏不迷路&#x1f496; 在银河麒麟高级服务器操作系统V10中&#xff0c;关闭定期锁屏功能很简单。使用场景&#xff1a;比如&#xff0c;当你…

大模型~合集6

我自己的原文哦~ https://blog.51cto.com/whaosoft/11566566 # 深度模型融合&#xff08;LLM/基础模型/联邦学习/微调等&#xff09; 23年9月国防科大、京东和北理工的论文“Deep Model Fusion: A Survey”。 深度模型融合/合并是一种新兴技术&#xff0c;它将多个深度学习模…

.NET CORE程序发布IIS后报错误 500.19

发布IIS后浏览时报错误500.19&#xff0c;同时配置文件web.config的路径中也存在问号“?”。 可能原因&#xff1a;没有安装运行时

CMU 10423 Generative AI:lec14(Vision Language Model:CLIP、VQ-VAE)

文章目录 1 概述2 CLIP (Used in GPT-V)3 VQ-VAE (Used in Gemini)**VQ-VAE 详细笔记****VQ-VAE 的模块组成与数据流** **1. 输入数据****2. 编码器&#xff08;Encoder&#xff09;****2.1 编码器的作用****2.2 数据流与维度变化****2.3 编码器输出** **3. 量化器&#xff08;…

手机使用指南:如何在没有备份的情况下从 Android 设备恢复已删除的联系人

在本指南中&#xff0c;您将了解如何从 Android 手机内存中恢复已删除的联系人。Android 诞生、见证并征服了 80% 的智能手机行业。有些人可能将此称为“非常大胆的宣言”&#xff0c;但最近的统计数据完全支持我们的说法。灵活性、高度改进的可用性和快速性是 Android 操作系统…

Qt QWidget控件

目录 一、概述 二、Qwidget常用属性及函数介绍 2.1 enable 2.2 geometry 2.3 windowTitle 2.4 windowIcon 2.5 cursor 2.6 font 设置字体样式 2.7 toolTip 2.8 focusPolicy焦点策略 2.9 styleSheet 一、概述 widget翻译而来就是小控件&#xff0c;小部件。…

10.3作业

基于TCP的快查云词典 仿照有道云词典功能&#xff0c;实现一个自己的云词典功能&#xff0c;可以查询单词和发音。 服务器描述&#xff1a;服务器启动后&#xff0c;等待客户端连接&#xff0c;完成以下操作&#xff1a; 1.创建用户表、单词表、历史表 2.注册&#xff1a;接…