Qt窗口定制
qt中的QWidget窗口支持窗体绘制,但是不支持窗口标题栏绘制,想要美观的界面,还需要自己去定制,下面我就介绍一种定制窗体的方法
一个窗口无非就3部分,标题栏、窗体和状态栏,接下来我定制的窗口没有状态栏,如果自己想加状态栏的话,照着这个模式自己也可以添加,说白了,窗口定制就是把完整的窗口分3部分定制,而每个部分又都是一个qt窗口
定制窗口效果图如下,根据个人喜好,自己也可以定制不同的效果
如图1所示,这个窗口包含两部分,标题栏和窗体,这两部分其实分别是一个没有标题栏的QWidget,接下来我分别介绍下这两部分
标题栏
构造函数代码如下
setAutoFillBackground(true);//自动填充背景色,防止继承父窗口背景色
setStyleSheet(QStringLiteral("background:blue;"));//背景色
setFixedHeight();//设置高度 看个人喜好 可以做微调
_p->minimize = new QToolButton(this);
_p->maximize = new QToolButton(this);
_p->close = new QToolButton(this);
/// 设置系统按钮图标.
QPixmap pix = style()->standardPixmap(QStyle::SP_TitleBarCloseButton);
_p->close->setIcon(pix);
_p->maxPix = style()->standardPixmap(QStyle::SP_TitleBarMaxButton);
_p->maximize->setIcon(_p->maxPix);
pix = style()->standardPixmap(QStyle::SP_TitleBarMinButton);
_p->minimize->setIcon(pix);
_p->restorePix = style()->standardPixmap(QStyle::SP_TitleBarNormalButton);
_p->minimize->setMinimumHeight();
_p->close->setMinimumHeight();
_p->maximize->setMinimumHeight();
_p->label = new QLabel(this);
_p->label->setAttribute(Qt::WA_TransparentForMouseEvents, true); //鼠标穿透
_p->label->setStyleSheet(QStringLiteral(" font-size:12px;\
font - weight:Bold"));
_p->label->setMargin();
SetWindowTitle("title");
QHBoxLayout *hbox = new QHBoxLayout;
hbox->addWidget(_p->label);
hbox->addWidget(_p->minimize);
hbox->addWidget(_p->maximize);
hbox->addWidget(_p->close);
//_p->maximize->setVisible(false);
hbox->insertStretch(, );
hbox->setSpacing();
connect(_p->minimize, &QToolButton::clicked, this, [this]{
BaseWidget * widget = qobject_cast(parent());
if (widget)
{
widget->SetWindowMovePos(widget->pos());
emit WindowDockedSignal();
}
});
connect(_p->maximize, &QToolButton::clicked, this, &TitleBar::showMaxRestore);
connect(_p->close, &QToolButton::clicked, this, [this]{emit WindowCloseSignal(_p->label->text()); });
hbox->setMargin();
hbox->setSpacing();
setLayout(hbox);
void TitleBar::showMaxRestore()//最大化或者还原
{
if (_p->maxNormal)
{
_p->maxNormal = !_p->maxNormal;
_p->maximize->setIcon(_p->maxPix);
}
else
{
_p->maxNormal = !_p->maxNormal;
_p->maximize->setIcon(_p->restorePix);
}
emit WindowMaxRestoreSignal(_p->maxNormal);
}
void TitleBar::SetWindowTitle(const QString & title)//设置窗口标题
{
if (_p)
{
_p->label->setText(title);
}
}
void TitleBar::SetWindowMaxable(bool isMax)
{
if (_p)
{
_p->maxNormal = isMax;
if (_p->maxNormal)
{
_p->maximize->setIcon(_p->maxPix);
}
else
{
_p->maximize->setIcon(_p->restorePix);
}
}
}
void TitleBar::mousePressEvent(QMouseEvent * event)//移动窗口
{
QPoint mousePos = _p->minimize->mapFromParent(event->pos());
if (_p->minimize->rect().contains(mousePos))//如果点击了最小化 则不能移动
{
return;
}
if (_p->maximize->rect().contains(mousePos))//如果点击了最大化不能移动
{
return;
}
_p->leftButtonPressed = true;
_p->startPos = event->globalPos();
_p->clickPos = mapToParent(event->pos());
}
void TitleBar::mouseReleaseEvent(QMouseEvent * event)
{
_p->leftButtonPressed = false;
}
void TitleBar::mouseMoveEvent(QMouseEvent * event)
{
if (_p->maxNormal)
{
return;
}
if (_p->leftButtonPressed)
{
parentWidget()->move(event->globalPos() - _p->clickPos);//移动父窗口
}
}
void TitleBar::mouseDoubleClickEvent(QMouseEvent * event)
{
showMaxRestore();
}
窗体定制
直接上代码
cpp如下
setFrameShape(Panel);
setMouseTracking(true);
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool);/// 隐藏窗口标题栏.
setFixedSize(, );
_p->m_mouse_down = false;
_p->m_titleBar = new TitleBar(this);
_p->m_titleBar->installEventFilter(this);
connect(_p->m_titleBar, &TitleBar::WindowDockedSignal
, this, [this]{
setFixedSize(_p->m_content->size());
setMinimumSize(, );
setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
_p->m_titleBar->setVisible(false);
});
connect(_p->m_titleBar, &TitleBar::WindowMaxRestoreSignal
, this, [this](bool isMax){
if (isMax)
{
showMaximized();
}
else
{
showNormal();
}
});
_p->m_content = new QWidget(this);
QPalette plt = _p->m_content->palette();
plt.setColor(QPalette::Window, QColor("#000000"));
_p->m_content->setPalette(plt);//设置背景色黑色
_p->m_content->setAutoFillBackground(true);
_p->m_content->setAttribute(Qt::WA_PaintOnScreen, true);
QVBoxLayout *vbox = new QVBoxLayout(this);
vbox->addWidget(_p->m_titleBar);
vbox->setStretchFactor(_p->m_titleBar, );
vbox->setMargin();
vbox->setSpacing();
QVBoxLayout *layout = new QVBoxLayout(this);
layout->addWidget(_p->m_content);
layout->setMargin();
layout->setSpacing();
vbox->addLayout(layout);
vbox->setStretchFactor(layout, );
TitleBar * BaseWidget::GetTitleBar() const
{
if (_p)
{
return _p->m_titleBar;
}
}
QWidget * BaseWidget::GetContentWidget() const
{
if (_p)
{
return _p->m_content;
}
}
BaseWidget::State BaseWidget::GetWindowState() const
{
if (_p)
{
return _p->state;
}
}
void BaseWidget::SetWindowState(BaseWidget::State state)
{
if (_p)
{
_p->state = state;
if (_p->state == _floating)
{
_p->m_titleBar->setVisible(true);
}
else
{
_p->m_titleBar->setVisible(false);
}
}
}
QPoint BaseWidget::GetWindowFloatPos() const
{
if (_p)
{
return _p->floatPostion;
}
}
void BaseWidget::SetWindowFloatPos(const QPoint & point)
{
if (_p)
{
_p->floatPostion = point;
}
}
QPoint BaseWidget::GetWindowMovePos() const
{
if (_p)
{
return _p->m_restorePos;
}
}
void BaseWidget::SetWindowMovePos(const QPoint & pos)
{
if (_p)
{
_p->m_restorePos = pos;
}
}
bool BaseWidget::eventFilter(QObject * object, QEvent * event)
{
if (object == _p->m_titleBar)
{
if (event->type() == QEvent::MouseMove)
{
QMouseEvent * mouseEvent = static_cast(event);
if (mouseEvent && mouseEvent->button() & Qt::LeftButton)
{
return true;//不做处理
}
}
}
return QWidget::eventFilter(object, event);
}
void BaseWidget::mousePressEvent(QMouseEvent * event)
{
if (event->button() == Qt::LeftButton)
{
_p->m_mouse_down = true;
_p->dragPostion = event->globalPos() - frameGeometry().topLeft();
event->accept();
}
}
void BaseWidget::mouseMoveEvent(QMouseEvent * event)
{
if (_p->state != _floating || isMaximized())//如果窗口不是悬浮状态 或者最大化 不允许拖动
{
return;
}
if (_p->m_mouse_down)
{
move(event->globalPos() - _p->dragPostion);
event->accept();
}
}
void BaseWidget::mouseReleaseEvent(QMouseEvent * event)
{
_p->m_mouse_down = false;
}
void BaseWidget::mouseDoubleClickEvent(QMouseEvent * event)
{
if (_p->state == _dock)
{
_p->state = _floating;
_p->m_titleBar->setVisible(true);
setParent(nullptr);
setWindowFlags(Qt::WindowStaysOnTopHint | Qt::FramelessWindowHint | Qt::Tool);
move(GetWindowMovePos());
show();
}
}
有如上两部分代码,功能基本可以实现
Qt窗口定制的更多相关文章
- 自定义QT窗口部件外观之QStyle
自定义QT窗口部件外观 重新定义Qt内置窗口部件的外观常用的方法有两种:一是通过子类化QStyle 类或者预定义的一个样式,例如QWindowStyle,来定制应用程序的观感:二是使用Qt样式表. Q ...
- 利用Qt Assistant 定制帮助文档
为了将Qt Assistant定制为自己应用程序的帮助文档浏览器.需要完成以下几步: 一.导入HTML格式的帮助文档 (1)首先,针对自己的应用程序创建HTML格式的帮助文档,请参见<Doxyg ...
- CentOS下Qt窗口透明效果失效,成黑色背景的问题
一.问题 Linux系统下Qt窗口的透明效果成了黑色,但同样的代码在windows机子上有透明效果,主要是修改系统的配置,仅在centos6.3及其以上版本实验过.其他系统可以相应配置. 二.问题运行 ...
- 深度探索QT窗口系统(五篇)
窗口作为界面编程中最重要的部分,没有窗口就没有界面,是窗口让我们摆脱了DOS时代,按钮是一个窗口,文本框是一个窗口,标签页是一个窗口,...一个窗口可以由多个窗口组成,每天我们都在与窗口打交道,当你打 ...
- 调色板类QPalette——包含了Qt窗口不见的颜色组(collor group),和Windows右键属性外观非常类似
QPalette类包含了Qt窗口不见的颜色组(collor group); 1.Active组,该组的颜色用户当前活动的(active)窗口,即具有键盘或鼠标焦点的窗口; 2.Inactive组,该组 ...
- QT窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透
qt 窗口置顶/真透明/背景模糊/非矩形/跳过任务栏分页器/无边框/无焦点点击/焦点穿透 窗口置顶qt 里是 setWindowFlags(Qt::WindowStaysOnTopHint)kde 里 ...
- Qt窗口操作函数(最大化,全屏,隐藏最大化,最小化)
Qt窗口中的一些小技术总结 //Qt主窗口没有最小化,最大化按钮且最大化显示 int main(int argc, char *argv[]) { QApplication a(argc, argv ...
- 初识Qt窗口界面
1.新建一个新的Qt Gui应用,项目名称随意,例如MyMainWindow,基类选择QMainWindow,类名为MainWindow. 2.项目建立后,双击mainwindow.ui文件,在界面的 ...
- qt 窗口控件自动调整大小
/******************************************************************** * qt 窗口控件自动调整大小 * * 在写gui的时候,希 ...
随机推荐
- 基于centos7系统部署cobbler
准备环境和下载cobbler 一,系统准备 虚拟机下要添加两个网卡.一个仅主机对内提供cobbler服务,一个桥接用来通外网 系统版本为:CentOS 7.5 内网ip :169.254.1.6 # ...
- 三、OpenStack创建域,项目,用户和角色,验证,创建客户端脚本
一.Identity服务为每个OpenStack服务提供身份验证服务. 身份验证服务使用域,项目,用户和 角色的组合. 1.创建service 项目 # openstack project creat ...
- 可变参数函数(stdarg.h)的使用
2013/5/3记录: stdarg.h是C语言中C标准函数库的头文件,stdarg是由standard(标准) arguments(参数)简化而来,主要目的为让函数能够接收可变参数. stdar ...
- tensorflow 使用 5 mnist 数据集, softmax 函数
用于分类 softmax 函数 手写数据识别:
- vue创建状态管理(vuex的store机制)
1:为什么说要是永远状态管理 在使用 Vue 框架做单页面应用时,我们时常会遇到传值,组件公用状态的问题.(子父间传值文章传送门) ,如果是简单的应用,兄弟组件之间通信还能使用 eventBus 来作 ...
- 大数据框架对比:Hadoop、Storm、Samza、Spark和Flink
转自:https://www.cnblogs.com/reed/p/7730329.html 今天看到一篇讲得比较清晰的框架对比,这几个框架的选择对于初学分布式运算的人来说确实有点迷茫,相信看完这篇文 ...
- Java 将键盘中的输入保存到数组
import java.util.Scanner; import java.util.InputMismatchException; public class saveInputToArr { pub ...
- 《SpringMVC从入门到放肆》十一、SpringMVC注解式开发处理器方法返回值
上两篇我们对处理器方法的参数进行了分别讲解,今天来学习处理器方法的返回值. 一.返回ModelAndView 若处理器方法处理完后,需要跳转到其它资源,且又要在跳转资源之间传递数据,此时处理器方法返回 ...
- Android 应用内悬浮控件实践总结
在工作中遇到一个需求,需要在整个应用的上层悬浮显示控件,目标效果如下图: 首先想到的是申请悬浮窗权限,OK~ 打开搜索引擎,映入眼帘的并不是如何申请,而是“Android 悬浮窗权限各机型各系统适配大 ...
- DHCP工作原理简析
引言 DHCP是网络体系结构中应用层的一个重要协议,它可以帮助我们对要连接到互联网的计算机进行IP地址等信息的配置.本文从DHCP的原理出发,就DHCP的工作过程 进行详细的探讨. 主要报文 发现报文 ...