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的时候,希 ...
随机推荐
- STL 贺习笔记
贺文链接www.cnblogs.com/zhouzhendong/p/STL.html C++ STL 的一些基础用法 前言 创建一个空的 vector ,我一直是这样写的: vector < ...
- 2018-2019-2 20175305实验一《Java开发环境的熟悉》实验报告
2018-2019-2 20175305实验一<Java开发环境的熟悉>实验报告 实验题目 实验一Java开发环境的熟悉-1 1).实验目的及要求 1.建立"自己学号exp1&q ...
- 学习随笔:Vue.js与Django交互以及Ajax和axios
1. Vue.js地址 Staticfile CDN(国内): https://cdn.staticfile.org/vue/2.2.2/vue.min.js unpkg:会保持和npm发布的最新的版 ...
- Spring Cloud微服务笔记(五)Feign
Feign 一.Feign概述 Feign是一个声明式的Web Service客户端.在Spring Cloud 中使用Feign,可以做到 使用HTTP请求访问远程服务,就像调用本地方法一样,同时它 ...
- pywin32模块安装
安装流程: 1.查看python版本和位数: 2.下载对应的的pywin32,下载目录任意 https://sourceforge.net/projects/pywin32/files%2Fpywin ...
- System.data.sqlclient.sqlexception:将截断字符串或二进制数据终止
System.data.sqlclient.sqlexception:将截断字符串或二进制数据终止. 错误原因:输入的字符串长度超过数据库设置的长度
- CentOS 7.3/Linux .net core sdk 安装
执行下列命令,安装.NET Core SDK(微软官方教程地址 https://www.microsoft.com/net/learn/get-started/linuxcentos) 点开链接,选择 ...
- Android Gradle Task
Tasks runnable from root project ------------------------------------------------------------ Androi ...
- js的七大设计原则--迪米特原则
一.什么是迪米特原则 迪米特原则也叫最少知道原则,一个类应该对其他对象保持最少的了解.通俗来讲,就是一个类对自己依赖的类知道的越少越好.因为类与类之间的关系越密切,耦合度越大,当一个类发生改变时,对另 ...
- python从入门到实践-7章用户输入和while循环
#!/user/bin/env python# -*- coding:utf-8 -*- # input() 可以让程序暂停工作# int(input('please input something: ...