目录
1、创建一个无边框窗口,添加拖拽和阴影:
(1)、项目创建:
(2)、UI设计:
1)、选择一个Widget容器
2)、调整容器的布局
3)、 更改shadowWidget样式表
(3)、程序设计:
1)、创建无边框窗口:
2)、重写鼠标事件:
3)、实例化阴影边框:
(4)、全部代码如下:
2、UI界面控件的操作,控件的组合。qss的定制,dll封装:
(1)、首先介绍一下Qt里面的大部分控件:
1)、布局(Layouts)
2)、弹簧(Spacers)
3)、按钮(Buttons)
4)、视图窗口部件(Item View Wdgets)
5)、容器(containers)
6)、输入部件(Input widgets)
7)、显示部件
(2)、UI设计
1)、添加控件
2)、布局
(3)、qss的定制
1)、qss的定制的意义
2)、改变缩小,放大,关闭按钮的qss。
(4)、程序设计
1)、最小化按钮事件
2)、关闭按钮事件
3)、最大化按钮事件
(5)、dll封装
1)、库的创建
2)、库的导出
3)、库的连接
(6)、程序运行结果
(7)、全部代码如下
补充:
1、QMainWindow(主窗口):为应用程序提供主窗口使用,提供标题栏、菜单栏、工具栏和状态栏等,适合创建具有多个子窗口、工具栏、菜单等复杂的应用程序界面。
2、QWidget(窗口部件):适合创建单个简单的用户界面。
3、QDialog(对话框):创建需要用户参与和有反馈的任务。
这里我们先创建一个无边框窗口选择QWidget。
原因:Widget容器有完善的事件处理机制(鼠标事件),程序设计的后面会出现鼠标事件。
达到随着显示页面大小的改变而改变容器的大小
在不包括容器的界面部分右键鼠标,选择布局
布局选择水平或者垂直即可,这个时候的容器会随着界面大小变化而变化
改变样式表:改变widget容器的背景颜色为白色
这个样式表是qss的定制,后面会介绍。先Apply后OK设置完毕。
思路:第一步去掉qt自带的程序运行边框,创建无边框窗口
//第一步去掉边框,不能移动,不能关闭
this->setWindowFlags(Qt::FramelessWindowHint);
运行截图:
此时的界面其实包含一个wiget容器,但是由于颜色相同看不见。这个时候界面无法移动和关闭需要重写鼠标事件。
在widget.h中声明三个鼠标事件(鼠标移动,鼠标点击,鼠标释放):
//声明三个鼠标事件
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
在widget.cpp中定义三个鼠标事件,达到可以拖拽窗口的目的
鼠标在(点击释放移动)界面中与界面左上角的位置z的大小是始终不变的。
代码部分:
鼠标移动事件:
//鼠标移动事件,获取最新的鼠标相对桌面的距离
//用这个距离减去鼠标想对于界面的距离求出界面与座面的距离
//调用x的move函数
void Widget::mouseMoveEvent(QMouseEvent *event)
{
QWidget::mouseMoveEvent(event);
QPoint y=event->globalPos();//鼠标相对于桌面左上角的位置
QPoint x=y-this->z;
this->move(x);
}
鼠标点击事件:
/鼠标点击事件的时候先获取三个元素分别是
//y鼠标相对于桌面左上角的距离,x是界面左上角相对于桌面左上角的距离
//z在界面中鼠标点击,和界面左上角位置相对不变。
void Widget::mousePressEvent(QMouseEvent *event)
{
QWidget::mousePressEvent(event);
QPoint y=event->globalPos();//鼠标相对于桌面左上角的位置
QPoint x =this->geometry().topLeft();//窗口左上角相对于桌面左上角的位置
this-> z = y-x;
}
鼠标释放事件:
//鼠标释放直接清空z
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
QWidget::mouseReleaseEvent(event);
this->z = QPoint();
}
去掉边框的界面没有分解。需要阴影化边框
首先我们直接采用阴影界面边框(会出现问题)
代码如下
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect();
shadow->setBlurRadius(10); //边框阴影像素
shadow->setColor(Qt::black); //边框的颜色
shadow->setOffset(0); //偏移量
//设置shadowWidget容器的边框,不能直接设置界面为阴影会出现问题
this->setGraphicsEffect(shadow);
这个黑色的其实是除了容器剩余的全部界面部分,他已经不属于是边框而是界面变成黑色。
所以我们使用设置容器边框变成像素10,黑色。并且同时隐藏把父窗口透明。
代码如下:
//第三步实例化阴影边框
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect();
shadow->setBlurRadius(10);//边框阴影像素
shadow->setColor(Qt::black);
shadow->setOffset(0);
//设置shadowWidget容器的边框,不能直接设置界面为阴影会出现问题
// this->setGraphicsEffect(shadow);
ui->shadowWidget->setGraphicsEffect(shadow);
this->setAttribute(Qt::WA_TranslucentBackground);//父窗口透明解决问题
运行结果:
这个是显示出来的容器有明显的阴影边框,并且可以移动。
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
//声明三个鼠标事件
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
private:
Ui::Widget *ui;
QPoint z;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include
#include //添加阴影
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
//第一步去掉边框,不能移动,不能关闭
this->setWindowFlags(Qt::FramelessWindowHint);
//第三步实例化阴影边框
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect();
shadow->setBlurRadius(10);//边框阴影像素
shadow->setColor(Qt::black);
shadow->setOffset(0);
//设置shadowWidget容器的边框,不能直接设置界面为阴影会出现问题
// this->setGraphicsEffect(shadow);
ui->shadowWidget->setGraphicsEffect(shadow);
this->setAttribute(Qt::WA_TranslucentBackground);//父窗口透明解决问题
//第四步布局的设计
}
Widget::~Widget()
{
delete ui;
}
//第二步定义鼠标的三个事件,窗口可以移动
//鼠标移动事件,获取最新的鼠标相对桌面的距离
//用这个距离减去鼠标想对于界面的距离求出界面与座面的距离
//调用x的move函数
void Widget::mouseMoveEvent(QMouseEvent *event)
{
QWidget::mouseMoveEvent(event);
QPoint y=event->globalPos();//鼠标相对于桌面左上角的位置
QPoint x=y-this->z;
this->move(x);
}
//鼠标点击事件的时候先获取三个元素分别是
//y鼠标相对于桌面左上角的距离,x是界面左上角相对于桌面左上角的距离
//z在界面中鼠标点击,和界面左上角位置相对不变。
void Widget::mousePressEvent(QMouseEvent *event)
{
QWidget::mousePressEvent(event);
QPoint y=event->globalPos();//鼠标相对于桌面左上角的位置
QPoint x =this->geometry().topLeft();//窗口左上角相对于桌面左上角的位置
this-> z = y-x;
}
//鼠标释放直接清空z
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
QWidget::mouseReleaseEvent(event);
this->z = QPoint();
}
main.cpp
#include "widget.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Widget w;
w.show();
return a.exec();
}
widget.ui
水平布局(Vertical Layout):各个控件水平排布,会随着窗口大小变化而变化。
垂直布局(Horizontal Layout):各个部件垂直排布,会随着窗口大小改变而改。
网状布局(Grid Layout):以表格形式将窗口或者部件排布,允许子部件灵活排布(适合复杂的布局),会随着窗口大小改变而改。
表单布局(Form Layout):各个部件按照顺序排布在每一行中,,会随着窗口大小改变而改。
垂直弹簧:保证控件在界面放大缩小的时候,相对于界面(或者其他部件)的垂直位置不变。
水平弹簧:保证控件在界面放大缩小的时候,相对于界面(或者其他部件)的水平位置不变。
按钮:按钮标签,用于描述按钮代表的操作或者命令,点击按钮可以处理事件,可以改变外观,可以增加图标
工具按钮:用于在工具栏、工具箱或工具栏中显示图标和文本,并提供与特定操作或工具相关的功能。
单选按钮:通常用于在多个互斥的选项中选择一个选项。用户只能从中选择一个选项,不能同时选择多个选项。
勾选按钮:用于表示一个二进制选项的状态,即选中或未选中。
命令链接按钮:呈现带有标题和说明文本的按钮,以执行特定的命令或操作。
对话框按钮:是一种用户界面控件,通常用于在对话框中显示一组操作按钮,例如确定、取消、应用等。
列表视图:以垂直列表的形式显示数据,每个数据项通常在一个单独的行中
树形视图:以树形结构显示数据,适用于有层级结构的数据。
表格试图:以表格形式显示数据,每行代表一个数据项,列代表属性(数据库)。
列视图: 以多列的形式显示数据,每个列可以有不同的数据类型。
5)、列表窗口部件(Item widgets)
列窗口:
树窗口:
表窗口:
分组容器:用于将相关的控件组织在一起。一般可以封装经常使用多个一些控件组合。
滚动区域容器:提供滚动功能以容纳较大的内容。
工具栏容器:用于放置工具按钮和其他小部件。
选项卡容器:用于在选项卡页之间切换显示内容。
堆叠容器:可以用于管理多个子部件,并在需要时显示其中一个。
框架容器:可以用于创建具有边框和背景的自定义容器。
最基本容器:可作为其他部件的父级容器。
停靠窗容器:可将部件或窗口停靠在主窗口中。
ComboBox(Combo Box):用于从预定义选项列表中选择一个选项的下拉框。
LineEdit(Line Edit):用于接收单行文本输入的文本框。
TextEdit(Text Edit):用于多行文本输入和显示的文本编辑框。
SpinBox(Spin Box):用于输入整数值的旋转框,可以通过上下箭头或手动输入进行调整。
DoubleSpinBox(Double Spin Box):用于输入浮点数值的旋转框,可以通过上下箭头或手动输入进行调整。
Slider(Horizontal Slider 或 Vertical Slider):用于通过滑块来选择数值范围的滑动条,可以水平或垂直显示。
常用的label: 用于显示文本或图像。可以用于展示静态文本、图标、图片等,并且支持字体、对齐方式等属性设置。
在上一个设计的基础上我们添加一些控件还有布局
三个按钮的属性:
1、将三个按钮和一个标签放入水平布局
2、把frame容器和水平布局这俩个进行布局,选择垂直布局
3、将frame容器的垂直策略改成expanding,将水平布局顶上去
4、按下快捷键预览布局 alt+shift+r,继续调整布局
5、注意这个时候的布局是和widget容器是有默认距离需要把距离设置为0.
6、把label里面的文字居中
7、最终运行UI
各种应用程序或者网页的右上边都会有缩小关闭和放大。并且还会有明显的颜色提醒。
例如网页的窗口:
所以我们使用qss的目的就是来改变控件的圆滑程度还有颜色,具体内容可以查找Qt的助手
1、关闭窗口定制qss
QPushButton
{
border: 2px solid #8f8f91;
//boder设置边框的整体样式,2px边框宽度2像素,solid边框样式为实线,#88f8f91是颜色
border-top-right-radius:5px;
//设置右上角圆角半径为5像素
min-width:42px;
//这个就是UI里面设置最小的按钮长宽为42
}
//鼠标移动到按钮上面的函数
QPushButton:hover
{
background-color:rgb(255, 0, 0)
//设置背景颜色,颜色可以用rgb来表示
}
//鼠标点击按钮的颜色
QPushButton:pressed
{
//颜色可以在样式表直接选择改变颜色,自动生成代码
background-color:rgb(197, 0, 0);
}
2、放大窗口定制qss
QPushButton
{
border: 2px solid #8f8f91;
border-radius:6px;
min-width:42px;
}
QPushButton:hover
{
background-color:rgb(73, 73, 109)
}
QPushButton:pressed
{
background-color:rgb(94, 94, 141)
}
3、缩小窗口定制qss
QPushButton
{
border: 2px solid #8f8f91;
border-radius:6px;
min-width:42px;
}
QPushButton:hover
{
background-color:rgb(73, 73, 109)
}
QPushButton:pressed
{
background-color:rgb(94, 94, 141)
}
最终的运行界面:
第一步将三个按钮的功能,首先分别转到各自的槽函数
在类中声明槽函数:
private slots:void on_btnMin_clicked();void on_btnClose_clicked();void on_btnMax_clicked();
在类外初始化槽函数:
注意:
1、窗口的关闭和缩小可以直接调用函数执行,但是窗口扩大需要进行判断。此时是最大化窗口,再次点击要还原。
2、我们的窗口是是有阴影边框,最大化的时候边框阴影像素设置为0,不是最大化设置默认。
//最小化按钮事件void Widget::on_btnMin_clicked(){this->showMinimized();}
void Widget::on_btnClose_clicked(){this->close();}
//最大化按钮事件void Widget::on_btnMax_clicked(){ //判断窗口是否选择是最大化,不是就最大化//是就还原。if(this->isMaximized()){ //没有最大化默认边距ui->viMain->setMargin(11);this->showNormal();}else{ //最大化边距是0ui->viMain->setMargin(0);this->showMaximized();}}
dll封装的意义:封装为DLL后,该模块的功能可以被其他程序共享和复用。而且,当需要更新或修复该模块时,只需要更新或替换DLL文件,而不必修改和重新编译整个应用程序,从而提高了开发效率。
1、创建完成会会生成俩个头文件,我们只是用其中的导出函数Q_DECL_EXPORT。
所以我们把这个头文件删除
2、在第一个头文件里面,我们导出这个类和自定义的函数,作为自己的库函数
#include
//Q_DECL_EXPORT用于导出函数和对象
class Q_DECL_EXPORT Lesson2lib
{
public:
Lesson2lib();
};
//通过用C语言的方式进行导出
extern "C" Q_DECL_EXPORT void testfunction();
注意:导出自定义函数需要声明用C导出,C++的编辑器会把这个函数名字改变,
3、在cpp文件中我们包含一个QMessageBox,方便库连接成功的时候有对话框显示
#include "lesson2lib.h"
#include
Lesson2lib::Lesson2lib()
{
}
void testfunction()
{
QMessageBox::information(0,"title","content");
//连接成功弹出对话框标题是title 内容是content
}
1、我们首先去掉影子构建,把编译之后的文件放在一起
2、编译这个库在Debug里面生成三个文件
3、复制三个文件到我们的项目文件
4、在项目文件中链接寻找库的目录
.pro
-L.代表当前路径,-l代表链接库文件,一般-l会去寻找开头是lib结尾是.a的文件。
会先出现我们的QMessage对话框
点击OK
功能不测试由于放大缩小和关闭不好展示
untitled.pro
#-------------------------------------------------
#
# Project created by QtCreator 2023-09-14T11:17:25
#
#-------------------------------------------------
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled1
TEMPLATE = app
#链接外部库寻找目录。
LIBS += -L. -llesson2lib
# The following define makes your compiler emit warnings if you use
# any feature of Qt which as been marked as deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS
# You can also make your code fail to compile if you use deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
SOURCES += main.cpp\
widget.cpp
HEADERS += widget.h
FORMS += widget.ui
widget.h
#ifndef WIDGET_H
#define WIDGET_H
#include
#include
#include"lesson2lib.h"
namespace Ui {
class Widget;
}
class Widget : public QWidget
{
Q_OBJECT
public:
explicit Widget(QWidget *parent = 0);
~Widget();
//声明三个鼠标事件
virtual void mouseMoveEvent(QMouseEvent *event);
virtual void mousePressEvent(QMouseEvent *event);
virtual void mouseReleaseEvent(QMouseEvent *event);
private slots:
void on_btnMin_clicked();
void on_btnClose_clicked();
void on_btnMax_clicked();
private:
Ui::Widget *ui;
QPoint z;
};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"
#include
#include //添加阴影
Widget::Widget(QWidget *parent) :
QWidget(parent),
ui(new Ui::Widget)
{
ui->setupUi(this);
testfunction();
Lesson2lib lib;
//第一步去掉边框,不能移动,不能关闭
this->setWindowFlags(Qt::FramelessWindowHint);
//第三步实例化阴影边框
QGraphicsDropShadowEffect *shadow = new QGraphicsDropShadowEffect();
shadow->setBlurRadius(10);//边框阴影像素
shadow->setColor(Qt::black);
shadow->setOffset(0);
//设置shadowWidget容器的边框,不能直接设置界面为阴影会出现问题
// this->setGraphicsEffect(shadow);
ui->shadowWidget->setGraphicsEffect(shadow);
this->setAttribute(Qt::WA_TranslucentBackground);//父窗口透明解决问题
//第四步布局的设计
}
Widget::~Widget()
{
delete ui;
}
//第二步定义鼠标的三个事件,窗口可以移动
//鼠标移动事件,获取最新的鼠标相对桌面的距离
//用这个距离减去鼠标想对于界面的距离求出界面与座面的距离
//调用x的move函数
void Widget::mouseMoveEvent(QMouseEvent *event)
{
QWidget::mouseMoveEvent(event);
QPoint y=event->globalPos();//鼠标相对于桌面左上角的位置
QPoint x=y-this->z;
this->move(x);
}
//鼠标点击事件的时候先获取三个元素分别是
//y鼠标相对于桌面左上角的距离,x是界面左上角相对于桌面左上角的距离
//z在界面中鼠标点击,和界面左上角位置相对不变。
void Widget::mousePressEvent(QMouseEvent *event)
{
QWidget::mousePressEvent(event);
QPoint y=event->globalPos();//鼠标相对于桌面左上角的位置
QPoint x =this->geometry().topLeft();//窗口左上角相对于桌面左上角的位置
this-> z = y-x;
}
//鼠标释放直接清空z
void Widget::mouseReleaseEvent(QMouseEvent *event)
{
QWidget::mouseReleaseEvent(event);
this->z = QPoint();
}
//最小化按钮事件
void Widget::on_btnMin_clicked()
{
this->showMinimized();
}
//关闭按钮事件
void Widget::on_btnClose_clicked()
{
this->close();
}
//最大化按钮事件
void Widget::on_btnMax_clicked()
{ //判断窗口是否选择是最大化,不是就最大化
//是就还原。
if(this->isMaximized())
{ //没有最大化默认边距
ui->viMain->setMargin(11);
this->showNormal();
}
else
{ //最大化边距是0
ui->viMain->setMargin(0);
this->showMaximized();
}
}
UI界面
库的头文件
#ifndef LESSON2LIB_H
#define LESSON2LIB_H
#include
//Q_DECL_EXPORT用于导出函数和对象
class Q_DECL_EXPORT Lesson2lib
{
public:
Lesson2lib();
};
//通过用C语言的方式进行导出
extern "C" Q_DECL_EXPORT void testfunction();
#endif // LESSON2LIB_H
库的cpp文件
#include "lesson2lib.h"
#include
Lesson2lib::Lesson2lib()
{
}
void testfunction()
{
QMessageBox::information(0,"title","content");
}