QT进阶之路:带命名空间的自定义控件在Qt设计器与qss中的使用技巧

发布于:2025-06-08 ⋅ 阅读:(17) ⋅ 点赞:(0)

0.前言

在大型QT项目中我们需要定义自己的自定义控件库,而这种自定义控件为了避免类名冲突往往都会将类放到特定的命名空间中,从而会在一些场景中导致使用上的问题,本篇文章主要介绍Qt自定义控件在Qt设计器中使用的问题和qss中样式的定义问题。

1.带命名空间Qt自定义类在QT设计器中的使用技巧

1.1 定义一个带命令空间QLabel自定义类

// ColorTextLabel.h


#ifndef COLORTEXTLABEL_H
#define COLORTEXTLABEL_H

#include <QLabel>
#include <QMetaObject>
#include <QMetaEnum>

namespace CustomCotrols
{
	class ColorTextLabel : public QLabel
	{
	    Q_OBJECT
	    Q_ENUMS(ColorMode)
	    Q_PROPERTY(ColorMode colorMode READ colorMode WRITE setColorMode NOTIFY colorModeChanged)
	
	public:
	    enum ColorMode {
	        Normal,
	        Success,
	        Warning,
	        Danger
	    };
	
	    explicit ColorTextLabel(QWidget *parent = nullptr);
	    ~ColorTextLabel();
	
	    ColorMode colorMode() const;
	    void setColorMode(ColorMode mode);
	
	signals:
	    void colorModeChanged(ColorMode mode);
	
	private:
	    ColorMode m_colorMode;
	};
}
#endif // COLORTEXTLABEL_H

#include “ColorTextLabel.h”

// ColorTextLabel.cpp
namespace CustomCotrols
{
	ColorTextLabel::ColorTextLabel(QWidget *parent) : QLabel(parent), m_colorMode(Normal)
	{
	    // 设置对象名称以便在QSS中引用
	    setObjectName("ColorTextLabel");
	    // 启用样式表中的属性选择器
	    setProperty("colorMode", Normal);
	}
	
	ColorTextLabel::~ColorTextLabel()
	{
	}
	
	ColorTextLabel::ColorMode ColorTextLabel::colorMode() const
	{
	    return m_colorMode;
	}
	
	void ColorTextLabel::setColorMode(ColorMode mode)
	{
	    if (m_colorMode != mode) {
	        m_colorMode = mode;
	        setProperty("colorMode", mode);
	        style()->unpolish(this);
	        style()->polish(this);
	        update();
	        emit colorModeChanged(mode);
	    }
	}
}

1.2 在QT设计器中引入自定义控件类

实际项目开发中为了提高开发效率,对于比较固定的页面我们都是通过Qt设计器进行布局的,而要在Qt设计器中使用自定义类,我们需要对Qt内置空间类进行提升。
在提升对话框上填写提升类名时需要将命名空间全部写上CustomCotrols::ColorTextLabel,写头文件时如果头文件有目录需要将目录也写上CustomControls/ColorTextLabel,这样就能正常使用带命名空间的自定义Qt类了。

2.带命名空间Qt自定义类在qss中的使用技巧

2.1 命名空间在 QSS 中的特殊语法

在 C++ 中,命名空间的写法是使用 “::”,比如MyNamespace::MyCustomWidget,用于明确标识类所属的命名空间,避免命名冲突。然而,在 QSS 中,这种写法会与 Q 的子控件写法产生冲突。为了解决这个问题,QSS 采用了 “–” 来表示命名空间 。

2.1 在QSS中定义带命名空间的样式

/* styles.qss */
CustomCotrols--ColorTextLabel {
    border: 1px solid #cccccc;
    border-radius: 4px;
    padding: 6px;
    min-height: 24px;
    color: #333333;
}

CustomCotrols--ColorTextLabel[colorMode="0"] { /* Normal */
    background-color: #f0f0f0;
}

CustomCotrols--ColorTextLabel[colorMode="1"] { /* Success */
    background-color: #d4edda;
    color: #155724;
    border-color: #c3e6cb;
}

CustomCotrols--ColorTextLabel[colorMode="2"] { /* Warning */
    background-color: #fff3cd;
    color: #856404;
    border-color: #ffeeba;
}

CustomCotrols--ColorTextLabel[colorMode="3"] { /* Danger */
    background-color: #f8d7da;
    color: #721c24;
    border-color: #f5c6cb;
}

3.在项目中使用带命名空间的Qt自定义控件类

// main.cpp (示例使用)
#include <QApplication>
#include "colortextlabel.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    // 加载QSS样式
    QFile styleFile(":/styles.qss");
    if (styleFile.open(QIODevice::ReadOnly | QIODevice::Text)) {
        QString styleSheet = styleFile.readAll();
        a.setStyleSheet(styleSheet);
        styleFile.close();
    }

    // 创建示例标签
    ColorTextLabel label("Hello World");
    label.setColorMode(ColorTextLabel::Success);
    label.show();

    return a.exec();
}

4.总结

带命名空间的QT类在QT设计器中和qss中使用时都需要把命名空间带上。