qt 无边框,可拖动, 有标题栏,的 子窗口

注意:这个窗口只是在调用osgearth的地球窗口时,其他场景没试过。

先描述一下:创建一个窗口,是mainframe的子窗口,想设置子窗口可拖动标题栏,且可设置背景色或透明度功能。

使用的时候,把这些文件添加到工程中即可。加载qss文件时,如果出现错误,这时候可能要改一下路径。

另外修改wgshowtdobject类名(文件名)时,要注意修改wgshowtdobject.ui的类名(文件名),也要注意修改头文件中的 WGSHOWTDOBJECT_H 。

basewidget类名和titlebar类名一般不用修改。

调用示例:

mainframe.h添加成员变量 

WgShowTDObject  *m_pWgShowObject;

mainframe.cpp中

   m_pWgShowObject = new WgShowTDObject(this);
   m_pWgShowObject->show();

把文件贴出来:

wgshowtdobject.h

wgshowtdobject.cpp

wgshowtdobject.ui

basewidget.h

basewidget.cpp

basewidget.ui

titlebar.h

titlebar.cpp

titlebar.ui

BaseWidget.qss

代码如下:

wgshowtdobject.h

#ifndef WGSHOWTDOBJECT_H
#define WGSHOWTDOBJECT_H

#include <QWidget>
#include "basewidget.h"

namespace Ui {
class WgShowTDObject;
}

class WgShowTDObject : public BaseWidget
{
    Q_OBJECT
public:
    explicit WgShowTDObject(QWidget *parent = 0);
    ~WgShowTDObject();

private:
    
signals:

public slots:
    
protected:
    
private slots:

private:
    Ui::WgShowTDObject *ui;
  
};

#endif // WGSHOWTDOBJECT_H

 

wgshowtdobject.cpp

#include "wgshowtdobject.h"
#include "ui_wgshowtdobject.h"
#include "public.h"
#include "apphelper.h"

WgShowTDObject::WgShowTDObject(QWidget *parent) :
    BaseWidget(parent),
    ui(new Ui::WgShowTDObject)
{
    ui->setupUi(centralWidget());

    this->setTitle(tr("111"));
    this->move(PanLeftForm_Width, TitlebarTop_Height);
}

WgShowTDObject::~WgShowTDObject()
{
    delete ui;
}

 

wgshowtdobject.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>WgShowTDObject</class>
 <widget class="QWidget" name="WgShowTDObject">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>455</width>
    <height>530</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
 </widget>
 <resources/>
 <connections/>
</ui>

 

basewidget.h

#ifndef BASEWIDGET_H
#define BASEWIDGET_H

#include <QFrame>

namespace Ui {
class BaseWidget;
}

class BaseWidget : public QFrame
{
    Q_OBJECT

public:
    enum SizeCategory
    {
        LARGE_SIZE,
        MIDDLE_SIZE,
        SMALL_SIZE
    };

public:
    explicit BaseWidget(QWidget *parent = 0);
    ~BaseWidget();

    QWidget *centralWidget();

    void setSizeType(const SizeCategory &category);
    void setTitle(const QString &title);

signals:
    void sigClose();

private:
    Ui::BaseWidget *ui;
};

#endif // BASEWIDGET_H

 

basewidget.cpp

#include "basewidget.h"
#include "ui_basewidget.h"

BaseWidget::BaseWidget(QWidget *parent) :
    QFrame(parent),
    ui(new Ui::BaseWidget)
{
    ui->setupUi(this);
    this->setObjectName("BaseWidget");
    this->setWindowFlags(Qt::Window | Qt::FramelessWindowHint);    //
    this->setAttribute(Qt::WA_TranslucentBackground);
    this->setAttribute(Qt::WA_NoSystemBackground, false);

    //ui->widgetContents->setContentsMargins(10, 10, 10, 10);

    this->setStyleSheet("BaseWidget.qss");//根据个人情况修改qss路径
    
    setSizeType(LARGE_SIZE);
    this->hide();
}

BaseWidget::~BaseWidget()
{
    delete ui;
}

QWidget * BaseWidget::centralWidget()
{
    return ui->widgetContents;
}

void BaseWidget::setSizeType(const BaseWidget::SizeCategory &category)
{
    switch (category) {
    case LARGE_SIZE:
    {
        this->setProperty("SizeType", "LargeSize");
        this->setFixedHeight(617);
        break;
    }
    case MIDDLE_SIZE:
    {
        this->setProperty("SizeType", "MiddleSize");
        this->setFixedHeight(478);
        break;
    }
    case SMALL_SIZE:
    {
        this->setProperty("SizeType", "SmallSize");
        this->setFixedSize(420, 307);
        break;
    }
    default:
        break;
    }
}

void BaseWidget::setTitle(const QString &title)
{
    ui->frameTitle->setTitle(title);
}

 

basewidget.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>BaseWidget</class>
 <widget class="QFrame" name="BaseWidget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>500</width>
    <height>617</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Fixed" vsizetype="Fixed">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="minimumSize">
   <size>
    <width>500</width>
    <height>617</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>500</width>
    <height>617</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Frame</string>
  </property>
  <property name="frameShape">
   <enum>QFrame::StyledPanel</enum>
  </property>
  <property name="frameShadow">
   <enum>QFrame::Raised</enum>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <property name="spacing">
    <number>0</number>
   </property>
   <property name="leftMargin">
    <number>0</number>
   </property>
   <property name="topMargin">
    <number>0</number>
   </property>
   <property name="rightMargin">
    <number>0</number>
   </property>
   <property name="bottomMargin">
    <number>0</number>
   </property>
   <item>
    <widget class="TitleBar" name="frameTitle">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="minimumSize">
      <size>
       <width>0</width>
       <height>50</height>
      </size>
     </property>
     <property name="maximumSize">
      <size>
       <width>16777215</width>
       <height>50</height>
      </size>
     </property>
     <property name="frameShape">
      <enum>QFrame::StyledPanel</enum>
     </property>
     <property name="frameShadow">
      <enum>QFrame::Raised</enum>
     </property>
    </widget>
   </item>
   <item>
    <widget class="QWidget" name="widgetContents" native="true">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>TitleBar</class>
   <extends>QFrame</extends>
   <header>titlebar.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

 

titlebar.h

#ifndef TITLEBAR_H
#define TITLEBAR_H

#include <QFrame>

namespace Ui {
class TitleBar;
}
class QMouseEvent;
class QPushButton;

class TitleBar : public QFrame
{
    Q_OBJECT

public:
    explicit TitleBar(QWidget *parent = 0);
    ~TitleBar();

    void setTitle(const QString &title);

private:
    void mousePressEvent(QMouseEvent* event);
    void mouseMoveEvent(QMouseEvent* event);
    void mouseReleaseEvent(QMouseEvent* event);
    void resizeEvent(QResizeEvent *event);

private:
    Ui::TitleBar *ui;
    bool                m_bMousePress;                    // 移动窗口的变量
    QPoint                m_StartMovePos;                    // 窗口开始移动的位置
    QPushButton*        m_pBtnClose;
};

#endif // TITLEBAR_H

 

titlebar.cpp

#include "titlebar.h"
#include "ui_titlebar.h"
#include <QMouseEvent>
#include <QPushButton>

TitleBar::TitleBar(QWidget *parent) :
    QFrame(parent),
    ui(new Ui::TitleBar),
    m_bMousePress(false)
{
    ui->setupUi(this);

//    m_pBtnClose = new QPushButton(this);
//    m_pBtnClose->setGeometry(this->width() - 28, 24, 22, 22);
//    m_pBtnClose->setObjectName("pushButton_close");
//    m_pBtnClose->setFixedSize(22, 22);
//    connect(m_pBtnClose, SIGNAL(clicked()), parentWidget(), SIGNAL(sigClose()));
}

TitleBar::~TitleBar()
{
    delete ui;
}

void TitleBar::setTitle(const QString &title)
{
    ui->label_title->setText(title);
}

void TitleBar::mousePressEvent(QMouseEvent* event)
{
    m_bMousePress = true;
    m_StartMovePos = event->globalPos();
}

void TitleBar::mouseMoveEvent(QMouseEvent* event)
{
    if (m_bMousePress)
    {
        QPoint movePoint = event->globalPos() - m_StartMovePos;            // 鼠标移动的向量差
        QPoint widgetPos = parentWidget()->pos();                        // 获取主窗口的位置
        m_StartMovePos = event->globalPos();
        int posX = widgetPos.x() + movePoint.x();
        int posY = widgetPos.y() + movePoint.y();

        QWidget *grandParent = parentWidget()->parentWidget();
        if (NULL != grandParent)
        {
            if (posX < grandParent->pos().x())
                posX = grandParent->pos().x();
            if (posX > grandParent->pos().x() + grandParent->width() - parentWidget()->width())
                posX = grandParent->pos().x() + grandParent->width() - parentWidget()->width();

            if (posY < grandParent->pos().y())
                posY = grandParent->pos().y();
            if (posY > grandParent->pos().y() + grandParent->height() - parentWidget()->height())
                posY = grandParent->pos().y() + grandParent->height() - parentWidget()->height();
        }
        
        parentWidget()->move(posX, posY);    // 移动父窗口
    }
}

void TitleBar::mouseReleaseEvent(QMouseEvent* event)
{
    m_bMousePress = false;
}

void TitleBar::resizeEvent(QResizeEvent * event)
{
    //m_pBtnClose->setGeometry(this->width() - 28, 24, 22, 22);
}

 

titlebar.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>TitleBar</class>
 <widget class="QFrame" name="TitleBar">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>500</width>
    <height>50</height>
   </rect>
  </property>
  <property name="sizePolicy">
   <sizepolicy hsizetype="Expanding" vsizetype="Expanding">
    <horstretch>0</horstretch>
    <verstretch>0</verstretch>
   </sizepolicy>
  </property>
  <property name="minimumSize">
   <size>
    <width>500</width>
    <height>50</height>
   </size>
  </property>
  <property name="maximumSize">
   <size>
    <width>500</width>
    <height>50</height>
   </size>
  </property>
  <property name="windowTitle">
   <string>Frame</string>
  </property>
  <property name="frameShape">
   <enum>QFrame::StyledPanel</enum>
  </property>
  <property name="frameShadow">
   <enum>QFrame::Raised</enum>
  </property>
  <layout class="QHBoxLayout" name="horizontalLayout">
   <property name="topMargin">
    <number>6</number>
   </property>
   <property name="bottomMargin">
    <number>6</number>
   </property>
   <item>
    <widget class="QLabel" name="label_title">
     <property name="sizePolicy">
      <sizepolicy hsizetype="Preferred" vsizetype="Preferred">
       <horstretch>0</horstretch>
       <verstretch>0</verstretch>
      </sizepolicy>
     </property>
     <property name="text">
      <string/>
     </property>
     <property name="alignment">
      <set>Qt::AlignCenter</set>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <resources/>
 <connections/>
</ui>

 

BaseWidget.qss

QFrame#BaseWidget
{
    background-color: rgba(0, 0, 0, 0.1);
    font-family:Microsoft YaHei;
}

QLabel
{
    font-size:22px;
    font-family:Microsoft YaHei;
    font-weight:normal;
    color:rgba(255,255,255,1);
    background-color: rgba(0,18,41, 0);
}

QLineEdit
{
    font-size:22px;
    font-family:Microsoft YaHei;
    font-weight:normal;
    color:rgba(255,255,255,1);
    background-color: rgba(0,18,41, 0);
}

QPushButton
{
    font-size:22px;
    color:rgb(255, 255, 255);  
    background: rgba(0, 153, 217, 0.4);  
    border:1px;  
    border-radius:2px;
    padding:2px 2px;
    font-family:Microsoft YaHei;
}
QPushButton:hover
{
    color:rgb(255, 255, 255);   
    border-style:solid;   
    background: rgba(0, 153, 217, 0.3);  
    border-radius:2px;
    border:1px;  
    font-family:Microsoft YaHei;
}

QPushButton:pressed
{
    color:rgb(255, 255, 255);   
    border-style:solid;  
    border-radius:2px;
    background: rgba(0, 153, 217, 0.2);  
    border:1px;
    font-family:Microsoft YaHei;
}

 

posted @ 2022-10-26 10:58  阳光下的小土豆  阅读(562)  评论(0编辑  收藏  举报