【二十七】【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.mzph.cn/news/880519.shtml

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

相关文章

书生大模型实战(从入门到进阶)L2-茴香豆:企业级知识库问答工具

目录 茴香豆介绍 茴香豆本地标准版搭建 环境搭建 配置服务器&#xff1a; 搭建茴香豆虚拟环境&#xff1a; 安装茴香豆 下载茴香豆 安装茴香豆所需依赖 下载模型文件 更改配置文件 知识库创建 测试知识助手 命令行运行 Gradio UI 界面测试 本文是对书生大模型L2-茴香…

SwiftUI简明概念(3):Path.addArc的clockwise方向问题

一、画个下半圆 SwiftUI中绘制下半圆的一个方法是使用Path.addArc&#xff0c;示例代码如下&#xff1a; var body: some View {Path { path inpath.addArc(center: CGPoint(x: 200, y: 370), radius: 50, startAngle: Angle(degrees: 0), endAngle: Angle(degrees: 180.0), …

自然语言处理实战项目:从基础到实战

自然语言处理实战项目&#xff1a;从基础到实战 自然语言处理&#xff08;Natural Language Processing, NLP&#xff09;是人工智能的重要分支&#xff0c;致力于让计算机能够理解、生成和处理人类语言。NLP 在搜索引擎、智能客服、语音助手等场景中扮演着关键角色。本文将带…

MyBatis-Plus分页查询

在实际开发中&#xff0c;对于大量数据的查询&#xff0c;可以通过分页查询的方式来减少查询量和提高查询效率。在 MyBatis-Plus 中&#xff0c;分页查询可以通过使用 Page 对象和 IService 接口提供的分页方法来实现。MyBatis-Plus 的分页插件 PaginationInnerInterceptor 提供…

基于单片机的水位检测系统仿真

目录 一、主要功能 二、硬件资源 三、程序编程 四、实现现象 一、主要功能 基于STC89C52单片机&#xff0c;DHT11温湿度采集温湿度&#xff0c;滑动变阻器连接ADC0832数模转换器模拟水位传感器检测水位&#xff0c;通过LCD1602显示信息&#xff0c;然后在程序里设置好是否…

【文件增量备份系统】MySQL百万量级数据量分页查询性能优化

&#x1f3af; 导读&#xff1a;本文针对大数据量下的分页查询性能问题进行了深入探讨与优化&#xff0c;最初查询耗时长达12秒&#xff0c;通过避免全表计数及利用缓存保存总数的方式显著提升了浅分页查询速度。面对深分页时依然存在的延迟&#xff0c;采用先查询倒数第N条记录…

时间序列LSTM实现

这个代码参考了时间序列预测模型实战案例(三)(LSTM)(Python)(深度学习)时间序列预测(包括运行代码以及代码讲解)_lstm预测模型-CSDN博客 结合我之前所学的lstm-seq2seq里所学习到的知识对其进行预测 import time import numpy as np import pandas as pd import torch import…

Meta Sapiens 人体AI模型

Meta 一直是开发图像和视频模型的领导者&#xff0c;现在他们又增加了一个新东西&#xff1a;Meta Sapiens。和Homo sapiens一样&#xff0c;这个模型也是关于人类的。它旨在执行与人类相关的任务&#xff0c;例如理解身体姿势、识别身体部位、预测深度&#xff0c;甚至确定皮肤…

算法课习题汇总(3)

循环日程表 设有N个选手进行循环比赛&#xff0c;其中N2M&#xff0c;要求每名选手要与其他N−1名选手都赛一次&#xff0c;每名选手每天比赛一次&#xff0c;循环赛共进行N−1天&#xff0c;要求每天没有选手轮空。 例如4个人进行比赛&#xff1a; 思路&#xff1a; 把表格…

Spring MVC 基本配置步骤 总结

1.简介 本文记录Spring MVC基本项目拉起配置步骤。 2.步骤 在pom.xml中导入依赖&#xff1a; <dependency><groupId>org.springframework</groupId><artifactId>spring-webmvc</artifactId><version>6.0.6</version><scope>…

通过WebTopo在ARMxy边缘计算网关上实现系统集成

随着工业互联网技术的发展&#xff0c;边缘计算成为了连接物理世界与数字世界的桥梁&#xff0c;其重要性日益凸显。边缘计算网关作为数据采集、处理与传输的核心设备&#xff0c;在智能制造、智慧城市等领域发挥着关键作用。 1. BL340系列概述 BL340系列是基于全志科技T507-…

MATLAB仿真实现图像去噪

摘要 数字图像处理是一门新兴技术&#xff0c;随着计算机硬件的发展&#xff0c;其处理能力的不断增强&#xff0c;数字图像的实时处理已经成为可能。由于数字图像处理的各种算法的出现&#xff0c;图像处理学科在飞速发展的同时逐渐向其他学科交叉渗透。数字图像处理是一种通过…

【目标检测】隐翅虫数据集386张VOC+YOLO

隐翅虫数据集&#xff1a;图片来自网页爬虫&#xff0c;删除重复项后整理标注而成 数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;386 标注…

电子电路的基础知识

电子电路是现代电子技术的基础&#xff0c;由电子元件&#xff08;如电阻、电容、电感、二极管、晶体管等&#xff09;和无线电元件通过一定方式连接而成的电路系统。 以下是对电子电路的详细概述&#xff1a; 一、定义与分类 定义&#xff1a;电子电路是指由电子器件和有关无…

240925-GAN生成对抗网络

GAN生成对抗网络 GAN&#xff0c;顾名思义&#xff0c;gan……咳咳&#xff0c;就是干仗嘛&#xff08;听子豪兄的课讲说这个名字还真的源于中文这个字&#xff09;&#xff0c;对应的就有两方&#xff0c;放在这里就是有两个网络互相对抗互相学习。类比武林高手切磋&#xff…

dev containers plugins for vscode构建虚拟开发环境

0. 需求说明 自用笔记本构建一套开发环境&#xff0c;用docker 虚拟插件 dev containers,实现开发环境的构建&#xff0c;我想构建一套LLMs的环境&#xff0c;由于环境配置太多&#xff0c;不想污染本地环境&#xff0c;所以选择隔离技术 1. 环境准备 vscodedocker 2. 步骤…

韦东山FreeRTOS笔记

介绍 这篇文章是我学习FreeRTOS的笔记 学的是哔哩哔哩韦东山老师的课程 在学习FreeRTOS之前已经学习过江协的标准库和一丢丢的超子说物联网的HAL了。他们讲的都很不错 正在更新&#xff0c; 大家可以在我的Gitee仓库中下载笔记源文件、项目资料等 笔记源文件可以在Notion…

idea.vmoptions 最佳配置

1. 推荐的 idea64.exe.vmoptions 配置&#xff1a; -Xms1024m -Xmx4096m -XX:ReservedCodeCacheSize512m -XX:UseG1GC -XX:SoftRefLRUPolicyMSPerMB50 -XX:CICompilerCount4 -XX:HeapDumpOnOutOfMemoryError -XX:-OmitStackTraceInFastThrow -Dsun.io.useCanonCachesfalse -Dj…

微服务JSR303解析部署使用全流程

目录 1、什么是JSR303校验 2、小试牛刀 【2.1】添加依赖 【2.2】添加application.yml配置文件修改端口 【2.3】创建实体类User 【2.4】创建控制器 【2.5】创建启动类 【注意】不必创建前端页面 3、规范返回值格式&#xff1a; 3.1添加ResultCode工具类 3.2添加Resul…

NASA数据集:ATLAS/ICESat-2 L3B 南极和北极网格陆地冰高,第 3 版

目录 简介 摘要 代码 引用 网址推荐 0代码在线构建地图应用 机器学习 ATLAS/ICESat-2 L3B Gridded Antarctic and Arctic Land Ice Height V003 简介 ATLAS/ICESat-2 L3B 南极和北极网格陆地冰高&#xff0c;第 3 版 ATL14 和 ATL15 将 ATLAS/ICESat-2 L3B 年度陆地冰…