无边框界面是每个桌面应用必备的功能。手机无边框就很好解决了,直接无边框就好了,默认是全屏的。但是桌面无边框会有很多问题,首先是不能拖动。
之前看过别人的无边框实现,大部分是做成整个界面按住哪里都能拖动,感觉这样不好。
另外看到大部分的代码都只实现了拖动,却没有实现标题栏。
还是自己做比较好。
// 无边框
setWindowFlags(Qt::FramelessWindowHint|Qt::WindowMinimizeButtonHint);
//QFrame * headFrame = new QFrame;
MyQFrame * headFrame = new MyQFrame;
connect(headFrame,SIGNAL(myQFramePress(QMouseEvent*)),this,SLOT(onMyQFramePress(QMouseEvent *)));
connect(headFrame,SIGNAL(myQFrameRelease(QMouseEvent*)),this,SLOT(onMyQFrameRelease(QMouseEvent *)));
// icon加载
QPixmap pixmapIcon;
pixmapIcon.load(":/img/headIcon.png");
QLabel * labelHeadIcon = new QLabel;
labelHeadIcon->setFixedSize(pixmapIcon.width(),pixmapIcon.height());
labelHeadIcon->setPixmap(pixmapIcon);
// 最小化按钮
QPixmap pixmapMin;
pixmapMin.load(":/img/miniBtn.png");
QPushButton * minBtn = new QPushButton;
minBtn->setFixedSize(pixmapMin.width(),pixmapMin.height());
minBtn->setIcon(pixmapMin);
minBtn->setIconSize(QSize(pixmapMin.width(),pixmapMin.height()));
minBtn->setCursor(Qt::PointingHandCursor);
minBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");//此种方法完美实现按钮透明背景
// 最大化按钮
QPixmap pixmapFull;
pixmapFull.load(":/img/fullBtn.png");
QPushButton * fullBtn = new QPushButton;
fullBtn->setFixedSize(pixmapFull.width(),pixmapFull.height());
fullBtn->setIcon(pixmapFull);
fullBtn->setIconSize(QSize(pixmapFull.width(),pixmapFull.height()));
fullBtn->setCursor(Qt::PointingHandCursor);
fullBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
// 关闭按钮
QPixmap pixmapClose;
pixmapClose.load(":/img/closeBtn.png");
QPushButton * closeBtn = new QPushButton;
closeBtn->setFixedSize(pixmapClose.width(),pixmapClose.height());
closeBtn->setIcon(pixmapClose);
closeBtn->setIconSize(QSize(pixmapClose.width(),pixmapClose.height()));
closeBtn->setCursor(Qt::PointingHandCursor);
closeBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
connect(minBtn,SIGNAL(clicked(bool)),SLOT(onMinBtnClick()));
connect(fullBtn,SIGNAL(clicked(bool)),SLOT(onFullBtnClick()));
connect(closeBtn,SIGNAL(clicked(bool)),SLOT(onCloseBtnClick()));
// 创建一个layout:标题栏
QHBoxLayout * headBoxLayout = new QHBoxLayout(headFrame);
headBoxLayout->setMargin(0);// 设置边距为0
headBoxLayout->addWidget(labelHeadIcon);// 添加左边的icon
headBoxLayout->addStretch(1);// 添加弹簧
headBoxLayout->addWidget(minBtn);
headBoxLayout->addWidget(fullBtn);
headBoxLayout->addWidget(closeBtn);
headFrame->setAutoFillBackground(true);
QColor color = QColor(37,37,118);
QPalette p = headFrame->palette();
p.setColor(QPalette::Window,color);
headFrame->setPalette(p);
headFrame->update();
注意,这个标题栏还要加入到主容器里:
QVBoxLayout * mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);// 设置边距为0
mainLayout->addWidget(headFrame);
我们设计的目标是在标题栏按下鼠标左键则可以移动窗口,而非在任何地方都能移动窗口。而QFrame不能实现这个功能,我们需要一个自定义的QFrame。
鼠标监听功能自QWidget就有了,而QFrame是继承自QWidget的。
(1)但是他并非已经实现了,他的监听回调是虚函数,需要自己去实现;
(2)我们想统一在主页面处理这些回调,而非在组件的类里面单独处理这些回调,那么,我们还需要给他添加信号,然后在主页面添加槽,完成信号的触发及调用。
myqframe.h:
#ifndef MYQFRAME_H
#define MYQFRAME_H
#include
class MyQFrame : public QFrame
{
Q_OBJECT
public:
explicit MyQFrame();
~MyQFrame();
protected:
void mousePressEvent(QMouseEvent *e);
void mouseMoveEvent(QMouseEvent *e);
void mouseReleaseEvent(QMouseEvent *e);
void mouseDoubleClickEvent(QMouseEvent *e);
signals:
void myQFramePress(QMouseEvent *e);// 注意,信号只需注册,并在cpp里调用,无需实现
void myQFrameRelease(QMouseEvent *e);
};
#endif // MYQFRAME_H
myqframe.cpp:
#include "myqframe.h"
#include
MyQFrame::MyQFrame()
{
this->setMouseTracking(true);// 此属性没有设为true则不会监听到mouseMove
}
MyQFrame::~MyQFrame()
{
}
void MyQFrame::mousePressEvent(QMouseEvent *e)
{
// 此事件只在此地触发,没必要让父窗口捕捉到,因此也就不需要抛出QFrame::mousePressEvent
myQFramePress(e);
}
void MyQFrame::mouseMoveEvent(QMouseEvent *e)
{
// 注意:在此抛出QFrame::mouseMoveEvent(e);则在父窗口可以接收到mouseMoveEvent事件,否则接收不到
// 另外,必须设置this->setMouseTracking(true);否则不能触发此回调函数
QFrame::mouseMoveEvent(e);
}
void MyQFrame::mouseReleaseEvent(QMouseEvent *e)
{
myQFrameRelease(e);
}
void MyQFrame::mouseDoubleClickEvent(QMouseEvent *e)
{
// qDebug()<<"doubleclick!";
}
dialog.h:
#ifndef DIALOG_H
#define DIALOG_H
#include
#include
#include
#include
namespace Ui {
class Dialog;
}
class Dialog : public QDialog
{
Q_OBJECT
public:
explicit Dialog(QWidget *parent = 0);
~Dialog();
private:
Ui::Dialog *ui;
initUI();
bool IsPressed;
QPoint startPoint;
private slots:
void onMyQFramePress(QMouseEvent *e);
void onMyQFrameRelease(QMouseEvent *e);
void onMinBtnClick();
void onFullBtnClick();
void onCloseBtnClick();
protected:
void mouseMoveEvent(QMouseEvent * e);
void keyPressEvent(QKeyEvent *);
};
#endif // DIALOG_H
dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
#include
#include
#include
#include
#include
#include
#include
#include
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
resize(QSize(800,600));
initUI();
IsPressed = false;
}
Dialog::initUI()
{
// 无边框
setWindowFlags(Qt::FramelessWindowHint|Qt::WindowMinimizeButtonHint);
// ______________________________设置标题栏_________________________________
// QFrame做背景
//QFrame * headFrame = new QFrame;
MyQFrame * headFrame = new MyQFrame;
connect(headFrame,SIGNAL(myQFramePress(QMouseEvent*)),this,SLOT(onMyQFramePress(QMouseEvent *)));
connect(headFrame,SIGNAL(myQFrameRelease(QMouseEvent*)),this,SLOT(onMyQFrameRelease(QMouseEvent *)));
// icon加载
QPixmap pixmapIcon;
pixmapIcon.load(":/img/headIcon.png");
QLabel * labelHeadIcon = new QLabel;
labelHeadIcon->setFixedSize(pixmapIcon.width(),pixmapIcon.height());
labelHeadIcon->setPixmap(pixmapIcon);
// 最小化按钮
QPixmap pixmapMin;
pixmapMin.load(":/img/miniBtn.png");
QPushButton * minBtn = new QPushButton;
minBtn->setFixedSize(pixmapMin.width(),pixmapMin.height());
minBtn->setIcon(pixmapMin);
minBtn->setIconSize(QSize(pixmapMin.width(),pixmapMin.height()));
minBtn->setCursor(Qt::PointingHandCursor);
minBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");//此种方法完美实现按钮透明背景
// 最大化按钮
QPixmap pixmapFull;
pixmapFull.load(":/img/fullBtn.png");
QPushButton * fullBtn = new QPushButton;
fullBtn->setFixedSize(pixmapFull.width(),pixmapFull.height());
fullBtn->setIcon(pixmapFull);
fullBtn->setIconSize(QSize(pixmapFull.width(),pixmapFull.height()));
fullBtn->setCursor(Qt::PointingHandCursor);
fullBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
// 关闭按钮
QPixmap pixmapClose;
pixmapClose.load(":/img/closeBtn.png");
QPushButton * closeBtn = new QPushButton;
closeBtn->setFixedSize(pixmapClose.width(),pixmapClose.height());
closeBtn->setIcon(pixmapClose);
closeBtn->setIconSize(QSize(pixmapClose.width(),pixmapClose.height()));
closeBtn->setCursor(Qt::PointingHandCursor);
closeBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
connect(minBtn,SIGNAL(clicked(bool)),SLOT(onMinBtnClick()));
connect(fullBtn,SIGNAL(clicked(bool)),SLOT(onFullBtnClick()));
connect(closeBtn,SIGNAL(clicked(bool)),SLOT(onCloseBtnClick()));
// 创建一个layout:标题栏
QHBoxLayout * headBoxLayout = new QHBoxLayout(headFrame);
headBoxLayout->setMargin(0);// 设置边距为0
headBoxLayout->addWidget(labelHeadIcon);// 添加左边的icon
headBoxLayout->addStretch(1);// 添加弹簧
headBoxLayout->addWidget(minBtn);
headBoxLayout->addWidget(fullBtn);
headBoxLayout->addWidget(closeBtn);
headFrame->setAutoFillBackground(true);
QColor color = QColor(37,37,118);
QPalette p = headFrame->palette();
p.setColor(QPalette::Window,color);
headFrame->setPalette(p);
headFrame->update();
// _____________________________关于本机_____________________________________
// 关于本机按钮
QPixmap pixmapAbout;
pixmapAbout.load(":/img/about.png");
QPushButton * aboutBtn = new QPushButton;
aboutBtn->setFixedSize(pixmapAbout.width(),pixmapAbout.height());
aboutBtn->setIcon(pixmapAbout);
aboutBtn->setIconSize(QSize(pixmapAbout.width(),pixmapAbout.height()));
aboutBtn->setCursor(Qt::PointingHandCursor);
aboutBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
// 创建一个layout:关于本机
QFrame * aboutFrame = new QFrame;
QHBoxLayout * aboutBoxLayout = new QHBoxLayout(aboutFrame);
aboutBoxLayout->setMargin(0);
aboutBoxLayout->addStretch(8);
aboutBoxLayout->addWidget(aboutBtn);
aboutBoxLayout->addStretch(1);
// ____________________________程序功能模块按钮_____________________________
QPixmap pixmapRunBtn;
pixmapRunBtn.load(":/img/runBtnWithTitle.png");
QPixmap pixmapReportBtn;
pixmapReportBtn.load(":/img/reportBtnWithTitle.png");
QPixmap pixmapClearBtn;
pixmapClearBtn.load(":/img/clearBtnWithTitle.png");
QPixmap pixmapDevelopBtn;
pixmapDevelopBtn.load(":/img/developBtnWithTitle.png");
QPushButton * runBtn = new QPushButton;
runBtn->setFixedSize(pixmapRunBtn.width(),pixmapRunBtn.height());
runBtn->setIcon(pixmapRunBtn);
runBtn->setIconSize(QSize(pixmapRunBtn.width(),pixmapRunBtn.height()));
runBtn->setCursor(Qt::PointingHandCursor);
runBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
QPushButton * reportBtn = new QPushButton;
reportBtn->setFixedSize(pixmapReportBtn.width(),pixmapReportBtn.height());
reportBtn->setIcon(pixmapReportBtn);
reportBtn->setIconSize(QSize(pixmapReportBtn.width(),pixmapReportBtn.height()));
reportBtn->setCursor(Qt::PointingHandCursor);
reportBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
QPushButton * clearBtn = new QPushButton;
clearBtn->setFixedSize(pixmapClearBtn.width(),pixmapClearBtn.height());
clearBtn->setIcon(pixmapClearBtn);
clearBtn->setIconSize(QSize(pixmapClearBtn.width(),pixmapClearBtn.height()));
clearBtn->setCursor(Qt::PointingHandCursor);
clearBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
QPushButton * developBtn = new QPushButton;
developBtn->setFixedSize(pixmapDevelopBtn.width(),pixmapDevelopBtn.height());
developBtn->setIcon(pixmapDevelopBtn);
developBtn->setIconSize(QSize(pixmapDevelopBtn.width(),pixmapDevelopBtn.height()));
developBtn->setCursor(Qt::PointingHandCursor);
developBtn->setStyleSheet("background-color: rgba(0, 0, 0, 0)");
QFrame * funcFrame = new QFrame;
QHBoxLayout * funcBoxLayout = new QHBoxLayout(funcFrame);
funcBoxLayout->setMargin(0);
funcBoxLayout->addStretch(3);
funcBoxLayout->addWidget(runBtn);
funcBoxLayout->addStretch(2);
funcBoxLayout->addWidget(reportBtn);
funcBoxLayout->addStretch(2);
funcBoxLayout->addWidget(clearBtn);
funcBoxLayout->addStretch(2);
funcBoxLayout->addWidget(developBtn);
funcBoxLayout->addStretch(3);
//____________________________公司logo___________________________
QPixmap pixmapLogo;
pixmapLogo.load(":/img/ze.jpg");
QLabel * labelLogo = new QLabel;
labelLogo->setFixedSize(pixmapLogo.width(),pixmapLogo.height());
labelLogo->setPixmap(pixmapLogo);
QFrame * logoFrame = new QFrame;
QHBoxLayout * logoBoxLayout = new QHBoxLayout(logoFrame);
logoBoxLayout->setMargin(0);
logoBoxLayout->addStretch(100);
logoBoxLayout->addWidget(labelLogo);
logoBoxLayout->addStretch(1);
// __________________________底部状态显示及版权声明_____________________
QLabel * labelStatus = new QLabel;
QFont fontStatus;
fontStatus.setPointSize(12);
labelStatus->setFont(fontStatus);
labelStatus->setText("2018/03/06 10:16:30 通讯成功");
QLabel * labelCopyRight = new QLabel;
QFont fontCopyRight;
fontCopyRight.setPointSize(12);
fontCopyRight.setFamily("Microsoft YaHei");
fontCopyRight.setBold(true);
labelCopyRight->setFont(fontCopyRight);
labelCopyRight->setText("Copyright(c) 科技股份有限公司.ALL RIGHT RESERVED");
QFrame * bottomFrame = new QFrame;
QHBoxLayout * bottomBoxLayout = new QHBoxLayout(bottomFrame);
bottomBoxLayout->setMargin(0);
bottomBoxLayout->addStretch(1);
bottomBoxLayout->addWidget(labelStatus);
bottomBoxLayout->addStretch(4);
bottomBoxLayout->addWidget(labelCopyRight);
bottomBoxLayout->addStretch(1);
// _____________________________主容器______________________________
QVBoxLayout * mainLayout = new QVBoxLayout(this);
mainLayout->setMargin(0);// 设置边距为0
mainLayout->addWidget(headFrame);
mainLayout->addStretch(5);
mainLayout->addWidget(aboutFrame);
mainLayout->addStretch(25);
mainLayout->addWidget(funcFrame);
mainLayout->addStretch(30);
mainLayout->addWidget(logoFrame);
mainLayout->addWidget(bottomFrame);
mainLayout->addStretch(1);
}
void Dialog::mouseMoveEvent(QMouseEvent *e)
{
if(IsPressed)
{
// 原理:移动相对位置
// QCursor::pos()鼠标位置
// startPoint起始位置
// move设置的是QWidget左上角的坐标
QPoint windowPos(QCursor::pos()-startPoint);
move(windowPos);
}
}
void Dialog::onMyQFramePress(QMouseEvent *e)
{
IsPressed = true;
startPoint = e->pos();
}
void Dialog::onMyQFrameRelease(QMouseEvent *e)
{
IsPressed = false;
}
void Dialog::onMinBtnClick()
{
this->showMinimized();
}
void Dialog::onFullBtnClick()
{
if(this->isFullScreen())
{
this->setWindowFlags(Qt::SubWindow);
this->showNormal();
}else
{
this->setWindowFlags(Qt::Window);
this->showFullScreen();
}
}
void Dialog::onCloseBtnClick()
{
QApplication::exit();
}
void Dialog::keyPressEvent(QKeyEvent * keyset)
{
if(keyset->key()==Qt::Key_Escape)
{
if(this->isFullScreen())
{
this->setWindowFlags(Qt::SubWindow);
this->showNormal();
}
}
}
Dialog::~Dialog()
{
delete ui;
}