我是靠谱客的博主 俭朴方盒,最近开发中收集的这篇文章主要介绍Qt 无边框 移动 缩放,隐藏标题栏,鼠标控制最小化,最大化,关闭 frameless.hframeless.cpp ,觉得挺不错的,现在分享给大家,希望可以做个参考。
概述
废话不多说,直接上代码
frameless.h
// "frameless.cpp"
// 参考
// https://www.cnblogs.com/findumars/p/6209705.html
// https://www.cnblogs.com/linuxAndMcu/p/10609182.html#_label0
// https://blog.csdn.net/haodemei2010/article/details/45533809
#ifndef FRAMELESS_H
#define FRAMELESS_H 1
//
#include<QWidget>
#include<QLabel>
#define TITLE_BAR 1
#if TITLE_BAR != 0
#include<QToolButton>
#include<QLabel>
#include<QDir>
#include<QStyle>
#endif
class Widget: public QWidget {
Q_OBJECT
public: //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
QLabel *ll;
explicit Widget(QWidget *parent = nullptr);
// fl == frameless 缩放 {{{
QPoint fl_mpoint; // 按下鼠标时的位置 mouse point
int fl_fw = 10, // 边框宽度 frame width
fl_mh = 100; // 最小化 鼠标右键下拖距离 minimum height
QRect fl_tr; // this矩形 this rect
int screen_w, screen_h, screen_p; // 宽,高,一份。width, height, portion
enum Efl_direction {
Center=0, Top, Bottom, Left, Right,
TopLeft, TopRight, BottomLeft, BottomRight //, Other
};
enum Efl_mouse_press {
MP_null=0, MP_left, MP_right };
Efl_direction fl_direction = Center; // 方向
Efl_mouse_press fl_mpress = MP_null; // 鼠标按键 mouse press
void fl_set_cursor(const QPoint &pos); // 设置指针
bool eventFilter(QObject *obj,QEvent *event) override; // 缩放 end }}}
#if TITLE_BAR != 0
QWidget *t_title_bar; // 标题栏 隐藏标题栏 {{{
QLabel *t_title; // 标题
QToolButton *t_close, // 关闭
*t_max, // 最大化/还原
*t_min; // 最小化
bool t_show; // 已显示?
void title_init(void); // 标题栏 初始化
void title_resize(void); // 标题栏 resize
void title_show(void); // 标题栏 显示
void title_hide(void); // 标题栏 隐藏 隐藏标题栏 end }}}
#endif
};
//
#endif
frameless.cpp
#include"frameless.h"
//#include"main.cpp"
//#include"frameless.pro"
#include<QApplication>
#include<QScreen>
#include<QMouseEvent>
#ifndef QT_NO_DEBUG
#include<QDebug>
#endif
// flag_qt_bug qt的bug
Widget::Widget(QWidget *parent): QWidget(parent) { // {{{
QSize screen_size = QGuiApplication::screens().first()->size();
screen_w = screen_size.width();
screen_h = screen_size.height();
screen_p = ((screen_h < screen_w)? screen_h/108 : screen_w/108);
// this_ = this;
fl_fw = screen_p; // 边框宽度 frame width
fl_mh = 10*screen_p; // 最小化 鼠标右键下拖距离 minimum height
this->setWindowFlags(Qt::FramelessWindowHint | // 设置无边框
Qt::WindowSystemMenuHint | Qt::WindowMinimizeButtonHint); // 点任务栏图标最小化
this->installEventFilter(this); // 安装事件过滤器
this->setMouseTracking(true); // 追踪鼠标
this->setMinimumSize(20*screen_p, 20*screen_p);
this->resize(screen_w/2, screen_h/2);
ll = new QLabel(this);
ll->setText(tr( "按住右键往下拖最小化n"
"双击左键或右键上拖最大化/还原n"
"双击右键关闭nn"
"如有乱码,n"
"把源文件保存为UTF-8编码即可n"
"(用记事本打开,另存为UTF-8编码)"));
ll->setStyleSheet(tr( "font-size: %1px;"
"color: #FF0055;").arg(5*screen_p));
ll->move(0, 0);
ll->resize(ll->sizeHint());
ll->setMouseTracking(true); // 追踪鼠标
// 子部件只要追踪鼠标就行,不要安装事件过滤器,
// 安装了事件过滤器后鼠标位置是子部件的位置,没安装就是this的位置
#if TITLE_BAR != 0
title_init();
#endif
} // }}}
#if TITLE_BAR != 0
// 隐藏标题栏 {{{
void Widget::title_init(void) { // {{{
t_show = false;
t_title_bar = new QWidget(this);
t_title_bar->move(0, 0);
t_title_bar->hide();
t_title_bar->setObjectName(tr("title_bar"));
t_title_bar->setStyleSheet(tr(
"QWidget#title_bar { background-color: #000000; }"
"QLabel { font: bold %1px; color: #FFFFFF; }"
).arg(3*screen_p));
t_title = new QLabel(t_title_bar);
t_title->move(screen_p, 0);
t_title->setAlignment(Qt::AlignVCenter);
t_title->setText(QFileInfo(QCoreApplication::applicationFilePath()).baseName()); // 程序名
t_title->resize(t_title->sizeHint().width(), 4*screen_p);
QToolButton **tbns[] = { &t_close, &t_max, &t_min };
QStringList slt = { "关闭", "最大化/还原", "最小化" };
int i;
Q_ASSERT(slt.size() == sizeof(tbns)/sizeof(*tbns));
for(i=0; i<slt.size(); ++i) {
*tbns[i] = new QToolButton(t_title_bar);
(*tbns[i])->resize(4*screen_p, 4*screen_p);
// (*tbns[i])->setAutoRaise(1);
(*tbns[i])->setToolTip(slt.at(i));
(*tbns[i])->setIconSize((*tbns[i])->size()); }
t_close->setIcon(style()->standardIcon(QStyle::SP_TitleBarCloseButton));
connect(t_close, SIGNAL(clicked()), this, SLOT(close()));
t_max->setIcon(style()->standardIcon(QStyle::SP_TitleBarMaxButton));
connect(t_max, &QAbstractButton::clicked, [&](){
((this->isMaximized())?
this->showNormal() : this->showMaximized()); }); // 最大化/还原
t_min->setIcon(style()->standardIcon(QStyle::SP_TitleBarMinButton));
connect(t_min, SIGNAL(clicked()), this, SLOT(showMinimized()));
i = t_title->width() + (3*4+2)*screen_p;
if(this->minimumWidth() < i)
this->setMinimumWidth(i);
} // }}}
inline void Widget::title_resize(void) { // {{{
t_title_bar->resize(this->width(), 4*screen_p);
t_close->move(t_title_bar->width() - t_close->width(), 0);
t_max->move(t_close->x() - t_max->width(), 0);
t_min->move(t_max->x() - t_min->width(), 0);
} // }}}
inline void Widget::title_show(void) { // {{{
if(!t_show) {
t_title_bar->show();
t_show = true; }
} // }}}
inline void Widget::title_hide(void) { // {{{
if(t_show) {
t_title_bar->hide();
t_show = false; }
} // }}}
// 鼠标 移动 标题栏 显示 隐藏 无分号 {{{
#define MOUSE_MOVE_TITLE_S_H_NO_SEMI(Y) if(Y < 6*screen_p)
title_show();
else
title_hide();
// }}}
// }}}
#endif
inline void Widget::fl_set_cursor(const QPoint &pos) { // 设置指针 {{{
int this_w = this->width(),
this_h = this->height(),
x = pos.x(),
y = pos.y();
if(x<fl_fw && y<fl_fw) { // 边框宽度 frame width
fl_direction = TopLeft;
this->setCursor(QCursor(Qt::SizeFDiagCursor)); }
else if(this_w-fl_fw<=x && y<fl_fw) {
fl_direction = TopRight;
this->setCursor(QCursor(Qt::SizeBDiagCursor)); }
else if(this_h-fl_fw<=y && x<fl_fw) {
fl_direction = BottomLeft;
this->setCursor(QCursor(Qt::SizeBDiagCursor)); }
else if(this_w-fl_fw<=x && this_h-fl_fw<=y) {
fl_direction = BottomRight;
this->setCursor(QCursor(Qt::SizeFDiagCursor)); }
else if(x < fl_fw) {
fl_direction = Left;
this->setCursor(QCursor(Qt::SizeHorCursor)); }
else if(this_w-fl_fw <= x) {
fl_direction = Right;
this->setCursor(QCursor(Qt::SizeHorCursor)); }
else if(y < fl_fw) {
fl_direction = Top;
this->setCursor(QCursor(Qt::SizeVerCursor)); }
else if(this_h-fl_fw <= y) {
fl_direction = Bottom;
this->setCursor(QCursor(Qt::SizeVerCursor)); }
else {
#if TITLE_BAR != 0
MOUSE_MOVE_TITLE_S_H_NO_SEMI(y)
#endif
fl_direction = Center;
this->unsetCursor(); }
} // }}}
bool Widget::eventFilter(QObject *obj,QEvent *event) { // 事件过滤器 {{{
if(event->type() == QEvent::MouseMove) { // 鼠标移动
QMouseEvent *met = static_cast<QMouseEvent *>(event);
if(MP_null == fl_mpress) {
if(!this->isMaximized()) { // 非最大化
// if(obj == this)
fl_set_cursor(met->pos());
// else
// fl_set_cursor(met->globalPos() - this->pos());
return 1; }
#if TITLE_BAR != 0
MOUSE_MOVE_TITLE_S_H_NO_SEMI(met->globalY() - this->y())
#endif
return 1; }
else if(MP_left == fl_mpress) {
if(fl_direction == Center)
this->move(met->globalPos() - fl_mpoint);
else {
switch(fl_direction) {
case Top:
if(this->minimumHeight() < fl_tr.bottom()-met->globalY()+2)
fl_tr.setY(met->globalY());
break;
case Bottom:
fl_tr.setBottom(met->globalY());
break;
case Left:
if(this->minimumWidth() < fl_tr.right()-met->globalX()+2)
fl_tr.setX(met->globalX());
break;
case Right:
fl_tr.setRight(met->globalX());
break;
case TopLeft:
if(this->minimumHeight() < fl_tr.bottom()-met->globalY()+2)
fl_tr.setY(met->globalY());
if(this->minimumWidth() < fl_tr.right()-met->globalX()+2)
fl_tr.setX(met->globalX());
break;
case TopRight:
if(this->minimumHeight() < fl_tr.bottom()-met->globalY()+2)
fl_tr.setY(met->globalY());
fl_tr.setRight(met->globalX());
break;
case BottomLeft:
if(this->minimumWidth() < fl_tr.right()-met->globalX()+2)
fl_tr.setX(met->globalX());
fl_tr.setBottom(met->globalY());
break;
case BottomRight:
fl_tr.setBottomRight(met->globalPos());
break;
default :
break; } // switch(fl_direction) end
this->setGeometry(fl_tr);
} // if(fl_direction != Center) end
return 1; } // else if(MP_left == fl_mpress) end
// else if(MP_right == fl_mpress)
return 1;
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// else if(obj != this) { // 非this的事件
// // return QWidget::eventFilter(obj, event);
// return 0;
// } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// else if(event->type() == QEvent::) { //
// return 1;
// } //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if(event->type() == QEvent::Resize) { // resize
#if TITLE_BAR != 0
title_resize();
#endif
return 1;
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#if TITLE_BAR != 0
else if(event->type() == QEvent::Leave) { // 鼠标离开窗口
title_hide();
return 1;
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#endif
else if(event->type() == QEvent::MouseButtonPress) { // 按下鼠标
QMouseEvent *met = static_cast<QMouseEvent *>(event);
switch(met->button()) {
case Qt::RightButton:
fl_mpress = MP_right;
fl_mpoint = met->pos();
// fl_mpoint = met->globalPos() - this->pos();
return 1;
case Qt::LeftButton:
if(!this->isMaximized()) { // 非最大化
fl_mpress = MP_left;
if(fl_direction == Center) {
this->setCursor(QCursor(Qt::SizeAllCursor));
fl_mpoint = met->pos(); }
// fl_mpoint = met->globalPos() - this->pos(); }
fl_tr = this->geometry(); }
return 1;
default :
return 0; }
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if(event->type() == QEvent::MouseButtonRelease) { // 松开鼠标
QMouseEvent *met = static_cast<QMouseEvent *>(event);
switch(fl_mpress) {
case MP_right:
if(fl_mpoint.y()+fl_mh <= met->y())
this->showMinimized(); // 最小化
else if(met->y() <= fl_mpoint.y()-fl_mh)
((this->isMaximized())?
this->showNormal() : this->showMaximized()); // 最大化/还原
break;
case MP_left:
if(fl_direction==Center && met->globalY()<fl_fw) {
this->setGeometry(fl_tr);
this->showMaximized(); }
break;
default : // 防警告
break; }
this->unsetCursor();
fl_mpress = MP_null;
return 1;
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
else if(event->type() == QEvent::MouseButtonDblClick) { // 鼠标双击
QMouseEvent *met = static_cast<QMouseEvent *>(event);
switch(met->button()) {
case Qt::LeftButton:
if(fl_direction == Center) {
((this->isMaximized())?
this->showNormal() : this->showMaximized()); } // 最大化/还原
return 1;
case Qt::RightButton:
this->close();
return 1;
default :
return 0; }
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#ifndef QT_NO_DEBUG
else if(event->type() == QEvent::KeyRelease) { // 按下键盘
QKeyEvent *ket = static_cast<QKeyEvent *>(event);
switch(ket->key()) {
case Qt::Key_D:
qDebug("(%d,%d), (%d,%d,%d,%d)",
this->width(), this->height(), this->x(), this->y(),
this->geometry().bottom(), this->geometry().right());
return 1;
default :
return 0; }
} //~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#endif
else
return QWidget::eventFilter(obj, event);
} // }}}
/* 边框 {{{
xxx.h
QWidget *frame_0, *frame;
xxx.cpp
构造函数 "screen_p=..."下面 "this->resize()"上面 (置于最底层)
frame_0 = new QWidget(this);
frame_0->setStyleSheet("background-color: #01000000;"); // 背景透明
frame = new QWidget(this);
frame->setMouseTracking(true); // 追踪鼠标
frame->setStyleSheet(tr(
"border: %1px outset #00AAFF;" // 边框:宽度 样式(solid,outset,inset) 颜色
"border-radius: %2px;" // 圆角
"background-color: #EEEEEE;" // 背景色
).arg((int)(0.5*screen_p)).arg(2*screen_p));
this->setAttribute(Qt::WA_TranslucentBackground); // 背景透明
在 "else if(event->type() == QEvent::Resize) { // resize" 里加上
frame_0->resize(this->size());
frame->resize(this->size());
边框 end }}} */
/* 坐标显示 {{{
#include<QToolTip>
在 "if(...QEvent::MouseMove)//鼠标移动"的"met=..." 下面加上
QToolTip::showText(QPoint(met->globalX(), met->globalY()-50),
tr("(%1,%2)").arg(met->pos().x()).arg(met->pos().y()), this);
坐标显示 end }}} */
最后
以上就是俭朴方盒为你收集整理的Qt 无边框 移动 缩放,隐藏标题栏,鼠标控制最小化,最大化,关闭 frameless.hframeless.cpp 的全部内容,希望文章能够帮你解决Qt 无边框 移动 缩放,隐藏标题栏,鼠标控制最小化,最大化,关闭 frameless.hframeless.cpp 所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复