Qt 一个自定义标题栏的QDockWidget

511 阅读1分钟

Qt 一个自定义标题栏的QDockWidget - 掘金 (juejin.cn)

效果

image.png

说明

  1. 主要利用了QDockWidget::setTitleBarWidget
  2. UI部分使用了dockheader.ui

相关代码

ZDockWidget.h

#pragma once

#include <QDockWidget>

QT_BEGIN_NAMESPACE
namespace Ui { class DockHeader; }
QT_END_NAMESPACE

class ZDockWidget : public QDockWidget {

Q_OBJECT

public:
    explicit ZDockWidget(QWidget *parent = nullptr, const Qt::WindowFlags &flags = Qt::WindowFlags());

    ~ZDockWidget() override;

    void addTitleBarAction(QAction *action);

    void setWindowTitle(const QString &title);

private:
    QWidget *createTitleBarWidget();

    void updateTitleBarActions();

private:
    Ui::DockHeader *ui{};
};

ZDockWidget.cpp

#include "zdockwidget.h"
#include "ui_dockheader.h"
#include <QActionEvent>

ZDockWidget::ZDockWidget(QWidget *parent, const Qt::WindowFlags &flags)
        : QDockWidget(parent, flags), ui(new Ui::DockHeader()) {
    setTitleBarWidget(createTitleBarWidget());
}

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

/**
 * 增加标题栏中的action
 */
void ZDockWidget::addTitleBarAction(QAction *action) {
    if (action) {
        ui->tb->addAction(action);
        updateTitleBarActions();
    }
}

/**
 * 创建标题栏
 */
QWidget *ZDockWidget::createTitleBarWidget() {
    auto *widget = new QWidget(this);
    ui->setupUi(widget);
    ui->btnSetting->setVisible(false);
    ui->vLine->setVisible(false);
    connect(ui->btnClose, &QToolButton::clicked, this, &ZDockWidget::close);
    return widget;
}

/**
 * 更新标题栏action
 * 若有action,则显示分隔的|
 */
void ZDockWidget::updateTitleBarActions() {
    bool show = !ui->tb->actions().isEmpty();
    ui->vLine->setVisible(show);
}

/**
 * 设置标题
 * @param title 标题
 */
void ZDockWidget::setWindowTitle(const QString &title) {
    ui->lblTitle->setText(title);
    QWidget::setWindowTitle(title);
}

dockheader.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>DockHeader</class>
 <widget class="QWidget" name="DockHeader">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>227</width>
    <height>25</height>
   </rect>
  </property>
  <layout class="QHBoxLayout">
   <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="QWidget" name="headGroup" native="true">
     <layout class="QHBoxLayout" name="horizontalLayout">
      <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="QLabel" name="lblTitle">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Preferred" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="minimumSize">
         <size>
          <width>0</width>
          <height>0</height>
         </size>
        </property>
        <property name="font">
         <font>
          <family>微软雅黑</family>
          <pointsize>9</pointsize>
          <italic>false</italic>
          <bold>false</bold>
         </font>
        </property>
        <property name="styleSheet">
         <string notr="true"/>
        </property>
        <property name="text">
         <string>标题</string>
        </property>
       </widget>
      </item>
      <item>
       <spacer name="horizontalSpacer">
        <property name="orientation">
         <enum>Qt::Horizontal</enum>
        </property>
        <property name="sizeHint" stdset="0">
         <size>
          <width>40</width>
          <height>20</height>
         </size>
        </property>
       </spacer>
      </item>
      <item>
       <widget class="QToolBar" name="tb">
        <property name="sizePolicy">
         <sizepolicy hsizetype="Expanding" vsizetype="Fixed">
          <horstretch>0</horstretch>
          <verstretch>0</verstretch>
         </sizepolicy>
        </property>
        <property name="movable">
         <bool>false</bool>
        </property>
        <property name="iconSize">
         <size>
          <width>16</width>
          <height>16</height>
         </size>
        </property>
        <property name="floatable">
         <bool>false</bool>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QWidget" name="vLine" native="true">
        <property name="minimumSize">
         <size>
          <width>1</width>
          <height>12</height>
         </size>
        </property>
        <property name="maximumSize">
         <size>
          <width>1</width>
          <height>12</height>
         </size>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QToolButton" name="btnSetting">
        <property name="maximumSize">
         <size>
          <width>22</width>
          <height>22</height>
         </size>
        </property>
        <property name="text">
         <string>...</string>
        </property>
        <property name="icon">
         <iconset resource="../../res/resources.qrc">
          <normaloff>:/light_theme/settings.svg</normaloff>:/light_theme/settings.svg</iconset>
        </property>
        <property name="autoRaise">
         <bool>true</bool>
        </property>
       </widget>
      </item>
      <item>
       <widget class="QToolButton" name="btnClose">
        <property name="toolTip">
         <string>关闭</string>
        </property>
        <property name="text">
         <string>...</string>
        </property>
        <property name="icon">
         <iconset resource="../../res/resources.qrc">
          <normaloff>:/light_theme/close.svg</normaloff>:/light_theme/close.svg</iconset>
        </property>
        <property name="autoRaise">
         <bool>true</bool>
        </property>
       </widget>
      </item>
     </layout>
    </widget>
   </item>
  </layout>
 </widget>
 <resources>
  <include location="../../res/resources.qrc"/>
 </resources>
 <connections/>
</ui>