239 lines
7.0 KiB
C++
239 lines
7.0 KiB
C++
#ifndef PICTEXTITEM_H
|
|
#define PICTEXTITEM_H
|
|
|
|
#include <QGraphicsTextItem>
|
|
#include <QPen>
|
|
#include <QGraphicsSceneMouseEvent>
|
|
#include <QImage>
|
|
|
|
#include <QXmlStreamAttributes>
|
|
#include <QHash>
|
|
|
|
class QFocusEvent;
|
|
class QGraphicsItem;
|
|
class QGraphicsScene;
|
|
class QGraphicsSceneMouseEvent;
|
|
|
|
enum ItemDirectionType {
|
|
NORMAL,
|
|
MIRROR_V,
|
|
MIRROR_H,
|
|
MIRROR_VH,
|
|
MIRROR_H_R270,
|
|
R90,
|
|
R270,
|
|
MIRROR_V_R270,
|
|
};
|
|
|
|
/**
|
|
* @brief 元素类型
|
|
* @remark
|
|
* 使用 @see PicTextItem::type() 获取元素类型
|
|
* 使用 @see PicTextItem::setSource 和 @see PicTextItem::source 读写item的来源
|
|
* 不同类型的元素,来源也不同
|
|
*/
|
|
enum SourceType{
|
|
UNKNOWN, // 未知, 目前未知类仅剩计数器类型
|
|
TEXT, // 文字类型,source: QString 文本字符串
|
|
IMAGE, // 图片类型, source: QString 图片位于本地的绝对路径
|
|
DATETIME, // 日期类型
|
|
SCHEDULE_SHIFT,
|
|
CODE, // 条形码和二维码
|
|
COUNTER,
|
|
};
|
|
|
|
class PicTextItem;
|
|
|
|
/**
|
|
* @brief 图元通用属性的ViewModel
|
|
*
|
|
* 目的:解耦UI编辑器与PicTextItem,支持灵活的数据绑定和批量操作。
|
|
* UI修改属性时先更新VM,再决定何时应用到item(实时或延迟)。
|
|
*/
|
|
struct TextItemModel {
|
|
// 图元类型,用于判断是否显示字间距
|
|
SourceType sourceType = SourceType::UNKNOWN;
|
|
|
|
ItemDirectionType direction = NORMAL;
|
|
int boldMultiple = 1;
|
|
int letterSpace = 0;
|
|
bool colorReversal = false;
|
|
QString fontFamily = "WenQuanYi7";
|
|
int fontSize = 9;
|
|
|
|
std::function<QImage()> imageGenerator; // 图片生成函数
|
|
|
|
// 便利方法:从PicTextItem快照创建VM
|
|
static TextItemModel fromItem(PicTextItem *item);
|
|
|
|
// 检查是否有改动
|
|
bool hasDifference(const TextItemModel &other) const {
|
|
return sourceType != other.sourceType ||
|
|
direction != other.direction ||
|
|
boldMultiple != other.boldMultiple ||
|
|
letterSpace != other.letterSpace ||
|
|
colorReversal != other.colorReversal;
|
|
}
|
|
|
|
static QString toString(const TextItemModel& model);
|
|
};
|
|
|
|
class PicTextItem : public QGraphicsTextItem
|
|
{
|
|
Q_OBJECT
|
|
public:
|
|
enum { Type = UserType + 3 };
|
|
explicit PicTextItem(QGraphicsItem *parent = 0, QGraphicsScene *scene = 0, const SourceType type = SourceType::UNKNOWN);
|
|
|
|
virtual ~PicTextItem();
|
|
|
|
// 重写 QGraphicsTextItem 的 type 方法,用于 Qt graphics 系统标识区别于内置 Item 类型
|
|
int type() const
|
|
{ return Type; }
|
|
|
|
SourceType sourceType() const { return m_sourceType; }
|
|
|
|
virtual QVariant source();
|
|
virtual void setSource(QVariant var);
|
|
|
|
// 粗体,即水平拉伸倍率, 1倍率为保持原样
|
|
int boldMultiple() { return m_boldMultiple; }
|
|
int setBoldMultiple(int multiple);
|
|
|
|
// 图元方向
|
|
ItemDirectionType direction() { return m_direction; }
|
|
void setDirection(ItemDirectionType dir);
|
|
|
|
// 颜色翻转
|
|
bool colorReversal() { return m_colorReversal; }
|
|
void setColorReversal(bool b);
|
|
|
|
// 设置字体使用该方法而不是 QGraphicsItem::setFont
|
|
void setCustomFont(QString name);
|
|
|
|
// 文字列间距
|
|
int letterSpace();
|
|
void setLetterSpace(int space);
|
|
|
|
/**
|
|
* @brief 重写 QGraphicsTextItem 的 paint 方法,用于自定义绘制文字
|
|
*/
|
|
virtual void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
|
|
|
|
/**
|
|
* @brief 重写 QGraphicsTextItem 的 boundingRect 方法,用于自定义计算文字的边界矩形
|
|
*/
|
|
virtual QRectF boundingRect() const override;
|
|
|
|
/**
|
|
* @brief 重写 QGraphicsTextItem 的 shape 方法,用于自定义计算文字的路径
|
|
*/
|
|
QPainterPath shape() const override;
|
|
|
|
/**
|
|
* @brief setAttrs 将从xml工程文件中读取到的图元属性集应用到图元
|
|
* @param attrs
|
|
* @remark
|
|
* 该方法在 @see TestPrintWidget 从xml文件中载入场景文件时被调用,用于恢复图元状态
|
|
* setAttrs 从属性集中读取 direction, boldMultiple, colorReversal, letterSpace, fontSize 并应用这些属性
|
|
* setAttrs 在最后会调用 @see setCustomAttrs , 子类可以实现该方法继续读取自定义的属性
|
|
*/
|
|
void setAttrs(const QXmlStreamAttributes& attrs);
|
|
|
|
/**
|
|
* @brief saveAttrs @see setAttrs 的反向操作,用于将图元的属性集保存到xml文件,@see TestPrintWidget 在保存场景文件时会调用此方法
|
|
* @param attrs 图元将属性集保存到 attrs
|
|
*/
|
|
void saveAttrs(QXmlStreamAttributes& attrs);
|
|
|
|
/**
|
|
* @brief applyModify 应用 方向、水平拉伸、属性更改
|
|
*/
|
|
void applyModify();
|
|
|
|
/**
|
|
* @brief preview 获取图元当前的预览
|
|
* @return
|
|
*/
|
|
QImage preview();
|
|
|
|
void setTextItemModel(const TextItemModel& model);
|
|
|
|
TextItemModel textItemModel();
|
|
|
|
QPointF clampItemPos(const QPointF& p);
|
|
|
|
signals:
|
|
void lostFocus(PicTextItem *item);
|
|
void selectedChange(QGraphicsItem *item);
|
|
void itemEdit(QString);
|
|
|
|
protected:
|
|
QVariant itemChange(GraphicsItemChange change, const QVariant &value);
|
|
void focusOutEvent(QFocusEvent *event);
|
|
void mouseDoubleClickEvent(QGraphicsSceneMouseEvent *event);
|
|
void mouseReleaseEvent(QGraphicsSceneMouseEvent * event);
|
|
void keyPressEvent(QKeyEvent *event);
|
|
|
|
/**
|
|
* @brief emptyImage 返回一张10x10的空图片
|
|
* @return
|
|
* @remark 用于子类在 source 为空时返回一张空图片,避免渲染错误
|
|
*/
|
|
QImage emptyImage();
|
|
|
|
/**
|
|
* @brief itemImage 子类可以重新实现该方法用于返回已经渲染好了的但未应用方向、水平拉伸的图像
|
|
* @return
|
|
* @remark
|
|
* 对图元进行方向、水平拉伸的步骤由 @see applyImgeTranslation 实现,因此子类不需要
|
|
*/
|
|
virtual QImage itemImage();
|
|
|
|
virtual void setCustomAttrs(const QXmlStreamAttributes& attrs);
|
|
|
|
virtual void saveCustomAttrs(QXmlStreamAttributes& attrs);
|
|
|
|
/**
|
|
* @brief colorReversalChanged 颜色翻转通知, 子类重写该方法用于响应属性变更
|
|
*/
|
|
virtual void colorReversalChanged();
|
|
|
|
/**
|
|
* @brief letterSpaceChanged 字间距更改通知, 子类重写该方法用于响应属性变更
|
|
*/
|
|
virtual void letterSpaceChanged();
|
|
|
|
/**
|
|
* @brief strToImage 将字符串渲染至图片
|
|
* @param str 要转换的字符串
|
|
* @return 渲染文字后的图片已经被裁剪至最小 boudningRect
|
|
* @remark
|
|
* 方向将应用 PicTextItem 的字体和颜色翻转进行渲染
|
|
*/
|
|
QImage strToImage(const QString& str);
|
|
|
|
public slots:
|
|
|
|
private:
|
|
|
|
QImage applyImgeTranslation(QImage img);
|
|
|
|
public:
|
|
const SourceType m_sourceType;
|
|
QVariant m_source;
|
|
bool SpecialConditions;
|
|
int CatchCnt1StartValue;
|
|
int CatchCnt1CurrValue;
|
|
|
|
int m_boldMultiple = 1;
|
|
ItemDirectionType m_direction = NORMAL;
|
|
bool m_colorReversal = false;
|
|
|
|
QImage m_itemImage;
|
|
QImage m_untransImage;
|
|
};
|
|
|
|
|
|
#endif // PICTEXTITEM_H
|