ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

Game Programming using Qt 5 Beginner’s Guide, 2nd Editio 学习笔记- outlinetext

2021-08-04 14:31:32  阅读:159  来源: 互联网

标签:const Qt Beginner color Programming OutlineTextItemBorder include border Outline


在这里插入图片描述

outlinetextitemborder.h

#ifndef OUTLINETEXTITEMBORDER_H
#define OUTLINETEXTITEMBORDER_H

#include <QObject>
#include <QColor>
//这是一个简单的基于 QObject 的类,包含许多属性
class OutlineTextItemBorder : public QObject {
    Q_OBJECT
    //您可以看到 Q_PROPERTY 宏没有我们迄今为止一直使用的 READ 和 WRITE 关键字
    //我们让 moc 生成代码,通过直接访问给定的类成员来对属性进行操作
    //MEMBER 关键字的好处在于,如果我们还提供 NOTIFY 信号,则生成的代码将在属性值更改时发出该信号
    Q_PROPERTY(int width MEMBER m_width NOTIFY widthChanged)
    Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
    Q_PROPERTY(Qt::PenStyle style MEMBER m_style NOTIFY styleChanged)
public:
    OutlineTextItemBorder(QObject *parent = 0);

    int width() const;
    QColor color() const;
    Qt::PenStyle style() const;
    QPen pen() const;
signals:
    void widthChanged(int);
    void colorChanged(QColor);
    void styleChanged(int);
private:
    int m_width;
    QColor m_color;
    Qt::PenStyle m_style;
};

#endif // OUTLINETEXTITEMBORDER_H

outlinetextitemborder.cpp

#include "outlinetextitemborder.h"
#include <QPen>

OutlineTextItemBorder::OutlineTextItemBorder(QObject *parent) :
    QObject(parent),
    m_width(0),
    m_color(Qt::transparent),
    m_style(Qt::SolidLine)
{

}

int OutlineTextItemBorder::width() const {
    return m_width;
}

QColor OutlineTextItemBorder::color() const {
    return m_color;
}

Qt::PenStyle OutlineTextItemBorder::style() const {
    return m_style;
}

QPen OutlineTextItemBorder::pen() const {
    QPen p;
    p.setColor(m_color);
    p.setWidth(m_width);
    p.setStyle(m_style);
    return p;
}

outlinetextitem.h

#ifndef OUTILINETEXTITEM_H
#define OUTILINETEXTITEM_H

#include <QQuickPaintedItem>
#include <QPainterPath>

class OutlineTextItemBorder;
//该类将为我们的主要项目类提供分组属性
class OutlineTextItem : public QQuickPaintedItem
{
    Q_OBJECT
    //除了颜色、字体和轮廓数据的分组属性之外,该界面还定义了要绘制的文本的属性
    //同样,我们使用 MEMBER 来避免必须手动实现 getter 和 setter
    Q_PROPERTY(QString text MEMBER m_text
                            NOTIFY textChanged)
    Q_PROPERTY(QColor color MEMBER m_color
                            NOTIFY colorChanged)
    Q_PROPERTY(OutlineTextItemBorder* border READ border
                            NOTIFY borderChanged)
    Q_PROPERTY(QString fontFamily MEMBER m_fontFamily
                            NOTIFY fontFamilyChanged)
    Q_PROPERTY(int fontPixelSize MEMBER m_fontPixelSize
                            NOTIFY fontPixelSizeChanged)
public:
    OutlineTextItem(QQuickItem *parent = 0);
    void paint(QPainter *painter);
    OutlineTextItemBorder* border() const;
    QPainterPath borderShape(const QPainterPath &path) const;
private slots:
    //我们也直接调用同一个槽来准备item的初始状态。
    void updateItem();
signals:
    void textChanged(QString);
    void colorChanged(QColor);
    void borderChanged();
    void fontFamilyChanged(QString);
    void fontPixelSizeChanged(int);
private:
    OutlineTextItemBorder* m_border;
    QPainterPath m_path;
    QRectF m_boundingRect;
    QString m_text;
    QColor m_color;
    QString m_fontFamily;
    int m_fontPixelSize;
};

#endif // OUTILINETEXTITEM_H

outlinetextitem.cpp

#include "outlinetextitem.h"
#include "outlinetextitemborder.h"
#include <QPainter>

OutlineTextItem::OutlineTextItem(QQuickItem *parent) :
    QQuickPaintedItem(parent)
{
    //我们基本上将来自对象及其分组属性对象的所有属性更改信号连接到同一个插槽
    //如果项目的任何组件被修改,该插槽将更新Item的数据
    m_border = new OutlineTextItemBorder(this);
    connect(this, &OutlineTextItem::textChanged,
            this, &OutlineTextItem::updateItem);
    connect(this, &OutlineTextItem::colorChanged,
            this, &OutlineTextItem::updateItem);
    connect(this, &OutlineTextItem::fontFamilyChanged,
            this, &OutlineTextItem::updateItem);
    connect(this, &OutlineTextItem::fontPixelSizeChanged,
            this, &OutlineTextItem::updateItem);
    connect(m_border, &OutlineTextItemBorder::widthChanged,
            this, &OutlineTextItem::updateItem);
    connect(m_border, &OutlineTextItemBorder::colorChanged,
            this, &OutlineTextItem::updateItem);
    connect(m_border, &OutlineTextItemBorder::styleChanged,
            this, &OutlineTextItem::updateItem);
    updateItem();
}

void OutlineTextItem::paint(QPainter *painter) {
    if(m_text.isEmpty()) return;
    painter->setPen(m_border->pen());
    painter->setBrush(m_color);
    painter->setRenderHint(QPainter::Antialiasing, true);
    painter->translate(-m_boundingRect.topLeft());
    painter->drawPath(m_path);
}

OutlineTextItemBorder *OutlineTextItem::border() const {
    return m_border;
}

QPainterPath OutlineTextItem::borderShape(const QPainterPath &path) const
{
    //borderShape() 函数返回一个新的画家路径,其中包括原始路径及其使用 QPainterPathStroker 对象创建的轮廓。 这是为了在计算边界矩形时正确考虑笔划的宽度。
    QPainterPathStroker pathStroker;
    pathStroker.setWidth(m_border->width());
    QPainterPath p = pathStroker.createStroke(path);
    p.addPath(path);
    return p;
}
//我们也直接调用同一个槽来准备item的初始状态。
void OutlineTextItem::updateItem() {
    //开始时,该函数重置作为绘制轮廓文本的后端的画家路径对象
    //并使用使用字体集绘制的文本对其进行初始化
    QFont font(m_fontFamily, m_fontPixelSize);
    m_path = QPainterPath();
    m_path.addText(0, 0, font, m_text);
    //槽使用我们将很快看到的 borderShape() 函数计算路径的边界矩形
    //我们使用 controlPointRect() 来计算边界矩形
    //因为它比 boundingRect() 快得多,并且返回一个大于或等于一个 boundingRect() 的区域
    m_boundingRect = borderShape(m_path).controlPointRect();
    setImplicitWidth(m_boundingRect.width());
    setImplicitHeight(m_boundingRect.height());
    //并要求项目使用 update() 调用重新绘制自身
    update();
}


main.qml

import QtQuick 2.9
import QtQuick.Window 2.3
import OutlineTextItem 1.0

Window {
    visible: true
    width: 800
    height: 400
    title: qsTr("Hello World")

    Rectangle {
        anchors.fill: parent
        OutlineTextItem {
            anchors.centerIn: parent
            text: "This is outlined text"
            fontFamily: "Arial"
            fontPixelSize: 64
            color: "#33ff0000"
            antialiasing: true
            border {
                color: "blue"
                width: 2
                style: Qt.DotLine
            }
        }
    }
}

main.cpp

#include <QQuickView>
#include <QGuiApplication>
#include <QtQml>
#include "outlinetextitem.h"
#include "outlinetextitemborder.h"

int main(int argc, char **argv) {
    QGuiApplication app(argc, argv);
    qmlRegisterUncreatableType<OutlineTextItemBorder>(
         "OutlineTextItem", 1, 0, "OutlineTextItemBorder", "");
    qmlRegisterType<OutlineTextItem>(
         "OutlineTextItem", 1, 0, "OutlineTextItem");

    QQmlApplicationEngine engine;
    engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
    if (engine.rootObjects().isEmpty())
      return -1;

    return app.exec();
}

标签:const,Qt,Beginner,color,Programming,OutlineTextItemBorder,include,border,Outline
来源: https://blog.csdn.net/TM1695648164/article/details/119382989

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有