[QML开发笔记]-QML扩展插件一(C++绘制控件)
QML扩展控件方法:通过c++绘制控件供QML使用。实现QML集成QWidget自绘制控件。
效果:
代码:
AnalogClock.h
#ifndef ANALOGCLOCK_H
#define ANALOGCLOCK_H
/**
* @FileName AnalogClock.h
* @brief File Description
* @author Kongdemin
* @date 2020-05
*/
#include <QQuickItem>
#include <QQuickPaintedItem>
class AnalogClock : public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QColor hourColor READ hourColor WRITE setHourColor NOTIFY hourColorChanged)
Q_PROPERTY(QColor minuteColor READ minuteColor WRITE setMinuteColor NOTIFY minuteColorChanged)
Q_PROPERTY(QColor secColor READ secColor WRITE setSecColor NOTIFY secColorChanged)
Q_PROPERTY(QColor bgColor READ bgColor WRITE setBgColor NOTIFY bgColorChanged)
public:
AnalogClock(QQuickItem *parent = nullptr);
QColor hourColor() const { return m_hourColor; }
QColor minuteColor() const { return m_minuteColor; }
QColor secColor() const { return m_secColor; }
QColor bgColor() const { return m_bgColor; }
signals:
void hourColorChanged(QColor hourColor);
void minuteColorChanged(QColor minuteColor);
void secColorChanged(QColor secColor);
void bgColorChanged(QColor bgColor);
public slots:
void setSecColor(QColor secColor)
{
if (m_secColor == secColor)
return;
m_secColor = secColor;
emit secColorChanged(m_secColor);
}
void setHourColor(QColor hourColor)
{
if (m_hourColor == hourColor)
return;
m_hourColor = hourColor;
emit hourColorChanged(m_hourColor);
}
void setMinuteColor(QColor minuteColor)
{
if (m_minuteColor == minuteColor)
return;
m_minuteColor = minuteColor;
emit minuteColorChanged(m_minuteColor);
}
void setBgColor(QColor bgColor)
{
if (m_bgColor == bgColor)
return;
m_bgColor = bgColor;
emit bgColorChanged(m_bgColor);
}
void paint(QPainter *painter) override;
Q_INVOKABLE void updatePaint();
private:
QColor m_hourColor;
QColor m_minuteColor;
QColor m_secColor;
QColor m_bgColor;
};
#endif // ANALOGCLOCK_H
AnalogClock.cpp
#include "AnalogClock.h"
#include <QPainter>
#include <QTime>
/**
* @FileName AnalogClock.cpp
* @brief File Description
* @author Kongdemin
* @date 2020-05
*/
AnalogClock::AnalogClock(QQuickItem *parent)
: QQuickPaintedItem(parent),
m_bgColor(QColor(Qt::white)),
m_hourColor(QColor(Qt::red)),
m_minuteColor(QColor(Qt::green)),
m_secColor(QColor(Qt::blue))
{
}
void AnalogClock::paint(QPainter *painter)
{
static const QPoint hourHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -40)
};
static const QPoint minuteHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -70)
};
static const QPoint secHand[3] = {
QPoint(7, 8),
QPoint(-7, 8),
QPoint(0, -85)
};
int side = qMin(width(), height());
QTime time = QTime::currentTime();
painter->fillRect(QRect(0, 0, this->width(), this->height()), m_bgColor);
painter->setRenderHint(QPainter::Antialiasing);
painter->translate(width() / 2, height() / 2);
painter->scale(side / 200.0, side / 200.0);
painter->setPen(Qt::NoPen);
painter->setBrush(m_hourColor);
painter->save();
painter->rotate(30.0 * ((time.hour() + time.minute() / 60.0)));
painter->drawConvexPolygon(hourHand, 3);
painter->restore();
painter->setPen(m_hourColor);
for (int i = 0; i < 12; ++i) {
painter->drawLine(88, 0, 96, 0);
painter->rotate(30.0);
}
painter->setPen(Qt::NoPen);
painter->setBrush(m_minuteColor);
painter->save();
painter->rotate(6.0 * (time.minute() + time.second() / 60.0));
painter->drawConvexPolygon(minuteHand, 3);
painter->restore();
painter->setPen(m_minuteColor);
for (int j = 0; j < 60; ++j) {
if ((j % 5) != 0)
painter->drawLine(92, 0, 96, 0);
painter->rotate(6.0);
}
painter->setPen(Qt::NoPen);
painter->setBrush(m_secColor);
painter->save();
painter->rotate(6.0 * time.second());
painter->drawConvexPolygon(secHand, 3);
painter->restore();
}
void AnalogClock::updatePaint()
{
update();
}
main.qml
import QtQuick 2.12
import QtQuick.Window 2.12
import KDMQuick 1.0
/**
* @FileName main.qml
* @brief File Description
* @author Kongdemin
* @date 2020-05
*/
Window {
visible: true
width: 640
height: 480
title: qsTr("QML集成QWidget自绘制控件")
AnalogClock{
id: analogClock
anchors.centerIn: parent
width: 350
height: 350
hourColor: "#8e44ad"
minuteColor: "#27ae60"
secColor: "#d35400"
}
Timer {
interval: 1000; running: true; repeat: true
onTriggered: analogClock.updatePaint()
}
}