使用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工程

工程文件下载,不完善之处,老铁们一块讨论。

  • 8
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值