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的时候,希 ...
随机推荐
- 今日报错Cannot access java.lang.String
public java.long.Long getId() { return id; } public void setId(java.lang.Long id) { this.id = id;} 手 ...
- vue 事件修饰符
1.用.stop来阻止冒泡(点击click按钮之后,先执行clickBtn2方法,然后执行clickBtn1方法,.stop命令阻止了clickBtn1方法的执行) 2.使用.prevent命令来阻止 ...
- JS与CSS那些特别小的知识点区别
1:target与currentTarget的区别 currentTarget指向的事件绑定的元素,target指向的是你点击的元素 2:attr与jprop在jQuery在API当中的区别 2.1: ...
- [OC] 各型号iPhone的屏幕分辨率与开发使用的数值
- Python入门经典. 以解决计算问题为导向的Python编程实践
Python入门经典. 以解决计算问题为导向的Python编程实践(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1juLsew8UiOErRheQPOuTaw 提取 ...
- NEERC训练实录
听说这里可以做一些idea比较好的题.. 那就做做吧 2017-2018 ACM-ICPC, NEERC, Northern Subregional Contest A. Auxiliary Proj ...
- Tesseract-ocr 工具使用记录
1.很多地方可以下载Tesseract-ocr工具,同时下载jTessBoxEditor方便之后的训练使用 2.下载Tesseract-ocr后可以放在任何地方,但是需要设置环境变量,或者在CMD当中 ...
- Vue 记录 Cannot read property '_withTask' of undefined
第二次遇到,年前偶尔代码中频繁出现过,因为没影响到交互,赶工期中,没有去深究. 今天又遇到了, 在事件触发后,脚本报错,终止了界面交互. 最后查找到这里的原因,检查并移除无效业务事件,错误消失了. ( ...
- 关于 Mybatis 设置懒加载无效的问题
看了 mybatis 的教程,讲到关于mybatis 的懒加载的设置: 只需要在 mybatis 的配置文件中设置两个属性就可以了: <settings> <!-- 打开延迟加载的开 ...
- H5 _浏览器通知功能使用
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...