[英]How to add property to custom control in Qt C++?
How do I properly add a property to a custom control, which when changed triggers the paint event? 如何正确地将属性添加到自定义控件,更改时会触发paint事件? The property only accepts an integer value of 0, 1 or 2.
该属性仅接受0,1或2的整数值。
The setter of the property would be called setPattern , so an example use would be setPattern(0) . 属性的setter将被称为setPattern ,因此使用示例将是setPattern(0) 。
This property value will eventually be used to control the pattern drawn in the paint event. 此属性值最终将用于控制在paint事件中绘制的模式。
labelheader.h labelheader.h
#ifndef LABELHEADER_H
#define LABELHEADER_H
#include <QLabel>
class LabelHeader : public QLabel
{
Q_OBJECT
public:
explicit LabelHeader(QWidget *parent = nullptr);
explicit LabelHeader(const QString &text, QWidget *parent = nullptr);
signals:
public slots:
// QWidget interface
protected:
void paintEvent(QPaintEvent *event);
};
#endif // LABELHEADER_H
labelheader.cpp labelheader.cpp
#include "labelheader.h"
#include <QPainter>
LabelHeader::LabelHeader(QWidget *parent) :
QLabel(parent)
{
}
LabelHeader::LabelHeader(const QString &text, QWidget *parent) :
QLabel(text, parent)
{
}
void LabelHeader::paintEvent(QPaintEvent *event)
{
// calculate font width
QFontMetrics metrics(font());
int text_width = metrics.boundingRect(text()).width();
// calculate dimensions
int y = height() * 0.5;
int x = text_width + 4;
// create pattern
QPixmap px(4, 4);
px.fill(Qt::transparent);
QPainter pattern_painter(&px);
// Create ashed 3 dots
pattern_painter.setPen(Qt::NoPen);
pattern_painter.setBrush(QBrush(palette().color(QPalette::WindowText), Qt::SolidPattern));
pattern_painter.drawRect(0, 0, 1, 1);
pattern_painter.drawRect(2, 2, 1, 1);
// draw
QPainter painter(this);
// Draw dashed 3 dots
painter.drawTiledPixmap(x, y-2, width()-x, 5, px);
// Draw solid line
//painter.drawLine(x,y,width(),y);
QLabel::paintEvent(event);
}
You can simply call update()
in the setter. 您只需在setter中调用
update()
即可。 If you want to only accept limited range of values, you can limit that in a setter or use an enum instead of an int. 如果您只想接受有限范围的值,可以在setter中限制它或使用枚举而不是int。
#include <QLabel>
class LabelHeader : public QLabel
{
Q_OBJECT
public:
Q_PROPERTY(Pattern pattern READ(getPattern) WRITE(setPattern))
enum Pattern { FIRST = 0, SECOND, THIRD };
Q_ENUM(Pattern)
...
void setPattern(Pattern value)
{
if (pattern != value)
{
pattern = value;
update();
}
}
Pattern getPattern() const { return pattern; }
...
private:
Pattern pattern { FIRST };
};
This is how I do it. 我就是这样做的。 NOTE: I haven't written an actual custom control in a "library", I usually just use "promoted widgets".
注意:我没有在“库”中编写实际的自定义控件,我通常只使用“提升的小部件”。
Header File: 头文件:
#ifndef MYWIDGET_H
#define MYWIDGET_H
#include <QObject>
#include <QWidget>
class MyWidget: public QWidget
{
Q_OBJECT
Q_PROPERTY(int value READ value WRITE setValue)
private:
int m_value;
public:
MyWidget(QWidget *parent=0);
inline int value() const {return m_value;}
void setValue(int value);
signals:
void valueChanged();
};
#endif // MYWIDGET_H
Source File: 源文件:
#include "MyWidget.h"
MyWidget::MyWidget(QWidget *parent)
:QWidget(parent)
{
m_value = 0;
}
void MyWidget::setValue(int value)
{
if (m_value == value) return;
m_value = value;
emit valueChanged();
update(); // This will cause repaint
}
To accomplish what you need you do not actually need QProperty , but a private attribute of your LabelHeader
class. 要实现您的需要,您实际上并不需要QProperty ,而是
LabelHeader
类的私有属性 。 Here is a step-by-step guide, covering all your requirements: 以下是分步指南,涵盖您的所有要求:
In LabelHeader.h add: 在LabelHeader.h中添加:
enum PatternType {
PatternOne = 0,
PatternTwo,
PatternThree
};
In LabelHeader.h add: 在LabelHeader.h中添加:
private:
PatternType m_pattern;
m_pattern
and select Refactor->Create Getter and Setter Member Functions m_pattern
并选择Refactor-> Create Getter和Setter Member Functions In the implementation of the setter invoke a paintEvent
by calling update()
, but only if the new pattern is different than the current one: 在setter的实现中,通过调用
update()
来调用paintEvent
,但paintEvent
是新模式与当前模式不同:
if (m_pattern == pattern) return; m_pattern = pattern; update();
In the constructor add m_pattern
to the initializer list to set its value by default 在构造函数中,将
m_pattern
添加到初始化列表中以默认设置其值
Use the value in the LabelHeader::paintEvent
to draw the corresponding pattern 使用
LabelHeader::paintEvent
的值绘制相应的模式
// draw tiled pixmap QPainter painter(this); switch (m_pattern) { case PatternOne: painter.drawTiledPixmap(x, y-2, w, 5, px); break; case PatternTwo: painter.drawTiledPixmap(x, y, w, 5, px); break; default: painter.drawTiledPixmap(x, y+2, w, 5, px); }
I have extended the example from this answer to cover your current requirements as well. 我已经从这个答案扩展了示例,以满足您当前的要求。 The full code is available on GitHub .
完整代码可在GitHub上获得 。
Regarding the use of Q_PROPERTY
, here is an important explanation kindly provided by @KubaOber: 关于
Q_PROPERTY
的使用,这是@KubaOber友情提供的重要解释:
Q_PROPERTY is a Qt idiom used to both convey a meaning to a human reader, and expose the property as such to the metatype system, making it easily scriptable from QML, etc.
Q_PROPERTY是一个Qt惯用语,用于向人类读者传达意义,并将属性暴露给元类型系统,使其易于从QML等编写脚本。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.