使用QT 开发不规则窗体
- 不规则窗体
- 贴图法的不规则窗体
- 创建UI模板
- 创建一个父类
- 创建业务窗体
- main函数直接调用user_dialog
- 创建QSS文件
- 完整的QT工程
不规则窗体
QT中开发不规则窗体有两种方法:(1)第一种方法,使用QWidget::setMask函数设置绘制区域,然后在paintEvent()绘制。(2)第二种方法,在窗体四周设置一圈QWidget,设置一些不规则的图片,达到不规则窗体的目的。本次介绍贴图的这种方法。
贴图法的不规则窗体
创建UI模板
在QT中创建一个UI窗体。
在上下左右不同的区域设置QWidget:(1)上方:左上角,右上角,上方正中是标题栏;(2)下方:左下角,下方正中,右下角。(3)窗体两侧(4)窗体正中是业务窗体的窗体,业务窗体下方放置两按钮【确定】【取消】
运行效果图:
创建一个父类
创建一个父类,用于显示不规则窗体的四周,以后的窗体就不用重新作,直接继承就可以了。为了简捷,就不用cpp,把代码直接写到头文件里。
#ifndef CUSTOM_DIALOG_BASE_H
#define CUSTOM_DIALOG_BASE_H
#include <QDialog>
#include <QDesktopWidget>
#include <QApplication>
#include <QMouseEvent>
#include <QDebug>
#include <QKeyEvent>
#include "ui_custom_dialog_base.h"
class custom_dialog_base : public QDialog
{
Q_OBJECT
public:
explicit custom_dialog_base(QWidget *parent = 0)
{
setWindowFlags(windowFlags() | Qt::FramelessWindowHint|Qt::Dialog);//无边框
this->setAttribute(Qt::WA_TranslucentBackground, true);//窗体背景全透明
ui.setupUi(this);
m_bMouseLeftButtonPressed = false;
m_bCtrlKeyPressed = false;
connect(ui.pushButton_close, &QPushButton::clicked, this, &QDialog::close);
connect(ui.pushButton_ok, &QPushButton::clicked, this, &QDialog::accept);
connect(ui.pushButton_cancel, &QPushButton::clicked, this, &QDialog::reject);
ui.label_title->installEventFilter(this);
}
~custom_dialog_base(){};
// 居中在父窗体中
void centerParent()
{
QWidget* parentWidget = this->parentWidget();
QRect rect = this->geometry();
QRect rectParent;
if(parentWidget != nullptr)
{
rectParent = parentWidget->geometry();
}
else
{
rectParent = QApplication::desktop()->geometry();
}
QPoint center = rectParent.center();
int width = rect.width();
int height = rect.height();
this->setGeometry(center.x()-width/2, center.y() - height/2, width, height);
}
// 设置标题
void setDialogTitle(const QString& strTitle)
{
ui.label_title->setText(strTitle);
}
//获取中间的内容面板
QWidget* getContainerWidget() { return ui.inner_frame; }
protected:
// ctrl键按下
virtual void keyPressEvent(QKeyEvent *event)
{
if (event->key() &Qt::Key_Control)
{
m_bCtrlKeyPressed = true;
this->setSizeGripEnabled(true);// ctrl键按下,显示窗体缩放抓手。
}
}
// ctrl键松开
virtual void keyReleaseEvent(QKeyEvent *event)
{
if (event->key() &Qt::Key_Control)
{
m_bCtrlKeyPressed = false;
this->setSizeGripEnabled(false);
}
}
// 窗体移动实现
bool eventFilter(QObject *obj, QEvent *event)
{
// ctrl键按下时返回
if (m_bCtrlKeyPressed)
{
return false;
}
// 判断是标题栏
if (obj == ui.label_title)
{
//鼠标左键按下
if (event->type() == QEvent::MouseButtonPress)
{
m_bMouseLeftButtonPressed = true;
m_pointMouseLeftButtonPressed = QCursor::pos();
return true;
}
else if (event->type() == QEvent::MouseButtonRelease)
{//鼠标左键松开
m_bMouseLeftButtonPressed = false;
return true;
}
else if (event->type() == QEvent::MouseMove && m_bMouseLeftButtonPressed)
{//鼠标左键按下时移动鼠标,开始移动窗体
QPoint offset = QCursor::pos() - m_pointMouseLeftButtonPressed;
QPoint pos = this->pos();
this->move(offset + pos);
m_pointMouseLeftButtonPressed = QCursor::pos();
return true;
}
}
return false;
}
private:
Ui_custom_dialog_base ui;
//鼠标是否按下
bool m_bMouseLeftButtonPressed;
//cltr键是否按下
bool m_bCtrlKeyPressed;
//按下后当前鼠标位置
QPoint m_pointMouseLeftButtonPressed;
};
// 可以pro文件中加入custom_dialog_base.h,不要下句
#include "./moc/moc_custom_dialog_base.cpp"
#endif // CUSTOM_DIALOG_BASE_H
创建业务窗体
业务窗体直接继承custom_dialog_base 类。同样,把cpp省去。把代码直接写到头文件里。
#ifndef USER_DIALOG_H
#define USER_DIALOG_H
#include <QDialog>
#include <QDesktopWidget>
#include <QApplication>
#include <QMouseEvent>
#include <QDebug>
#include <QKeyEvent>
#include "ui_user_dialog.h"
#include "custom_dialog_base.h"
class user_dialog : public custom_dialog_base
{
Q_OBJECT
public:
explicit user_dialog(QWidget *parent = 0)
{
ui.setupUi(getContainerWidget());// 加载业务窗体,
getContainerWidget()->setLayout(ui.formLayout_2);// 设置业务窗体的布局器到父类中的容器中。
ui.formLayout_2->setSpacing(15);
}
~user_dialog(){};
private:
Ui_user_dialog ui;
};
// 可以在pro文件中加入user_dialog.h,不要下句
#include "./moc/moc_user_dialog.cpp"
#endif // USER_DIALOG_H
main函数直接调用user_dialog
在main里直接创建user_dialog的实例,显示不规则窗体。
#include <QApplication>
#include <QDir>
#include <QPushButton>
#include "user_dialog.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QFile file;
QString strFile = QDir(QApplication::applicationDirPath()).canonicalPath() + "/ui.qss";
file.setFileName(strFile);
file.open(QFile::ReadOnly);
file.seek(0);
QString strQss= file.readAll();// 从ui.qss文件中读取样式
a.setStyleSheet(strQss); // 设置样式
user_dialog dlg;
dlg.setDialogTitle(QString::fromLocal8Bit("窗体标题"));
dlg.centerParent();// 居中父窗体。
return dlg.exec();
}
创建QSS文件
把使用自己喜欢的图片放到资源文件中,供QSS文件使用。
qss文件:
QWidget#widget_topleft{
background-color:transparent;
border-image:url(:/resources/top_left.png);
}
QWidget#widget_topcenter{
background-color:transparent;
border-image:url(:/resources/top_center.png);
}
QWidget#widget_topright{
background-color:transparent;
border-image:url(:/resources/top_right.png);
}
QWidget#widget_bottomleft{
background-color:transparent;
border-image:url(:/resources/bottom_left.png);
}
QWidget#widget_bottom_center{
background-color:transparent;
border-image:url(:/resources/bottom_center.png);
}
QWidget#widget_bottomright{
background-color:transparent;
border-image:url(:/resources/bottom_right.png);
}
QWidget#widget_left{
background-color:transparent;
border-image:url(:/resources/left_center.png);
}
QWidget#widget_center{
background-color:transparent;
border-image:url(:/resources/center.png);
}
QWidget#widget_right{
background-color:transparent;
border-image:url(:/resources/right_center.png);
}
QPushButton#pushButton_close{
background-color: transparent;
background-image:url(:/resources/pushButton_close.png);
}
QLabel{
font-size:16px;
color:white;
}
QLabel#label_title{
background-color: transparent;
text-align: center;
font-size:18px;
color:white;
}
QLineEdit, QComboBox,QDateTimeEdit,QSpinBox {
font-size:18px;
}
QSizeGrip {
image: url(:/resources/resize_gripper.png);
width: 32px;
height: 32px;
}
QPushButton#pushButton_ok,QPushButton#pushButton_cancel {
background-color: transparent;
border-image:url(:/resources/pushbutton.png);
min-width:96px;
min-height:32px;
}
QPushButton#pushButton_ok:pressed,QPushButton#pushButton_cancel:pressed {
background-color: transparent;
border-image:url(:/resources/pushbutton_pressed.png);
}
QPushButton#pushButton_ok:hover,QPushButton#pushButton_cancel:hover {
background-color: transparent;
border-image:url(:/resources/pushbutton_hover.png);
}
qrc文件:
<RCC>
<qresource prefix="/">
<file>./resources/top_left.png</file>
<file>./resources/top_center.png</file>
<file>./resources/top_right.png</file>
<file>./resources/left_center.png</file>
<file>./resources/center.png</file>
<file>./resources/right_center.png</file>
<file>./resources/bottom_left.png</file>
<file>./resources/bottom_center.png</file>
<file>./resources/bottom_right.png</file>
<file>./resources/pushButton_close.png</file>
<file>./resources/resize_gripper.png</file>
<file>./resources/pushbutton.png</file>
<file>./resources/pushbutton_pressed.png</file>
<file>./resources/pushbutton_hover.png</file>
</qresource>
</RCC>
完整的QT工程
工程文件下载,不完善之处,老铁们一块讨论。