修改日期类型图元大小计算方式,以可能最长的长度计算
This commit is contained in:
+126
-2
@@ -1,9 +1,80 @@
|
|||||||
#include "PicDateItem.h"
|
#include "PicDateItem.h"
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QRegExp>
|
#include <QRegExp>
|
||||||
|
#include <QPainter>
|
||||||
|
#include <QElapsedTimer>
|
||||||
#include "LogInfo.h"
|
#include "LogInfo.h"
|
||||||
#include "ItemCommon.h"
|
#include "ItemCommon.h"
|
||||||
|
|
||||||
|
// 生成可能的最长时间字符串供尺寸计算使用(基于像素宽度)
|
||||||
|
static QString generateMaxDateTimeString(const DateItemModel &model, const QFont &font)
|
||||||
|
{
|
||||||
|
if (model.datetimePattern.isEmpty())
|
||||||
|
return QString();
|
||||||
|
|
||||||
|
QString s = model.datetimePattern;
|
||||||
|
|
||||||
|
QFontMetrics fm(font);
|
||||||
|
|
||||||
|
auto longestFromList = [&fm] (const QStringList &lst, const QString &fallback) {
|
||||||
|
int bestW = -1;
|
||||||
|
QString best;
|
||||||
|
for (const auto &v : lst) {
|
||||||
|
int w = fm.horizontalAdvance(v);
|
||||||
|
if (w > bestW) { bestW = w; best = v; }
|
||||||
|
}
|
||||||
|
return best.isEmpty() ? fallback : best;
|
||||||
|
};
|
||||||
|
|
||||||
|
int i = s.indexOf("yyyy");
|
||||||
|
if (i != -1) {
|
||||||
|
QString repl;
|
||||||
|
if (!model.yearsMap.isEmpty()) {
|
||||||
|
for (auto v : model.yearsMap.values()) if (v.length() > repl.length()) repl = v;
|
||||||
|
} else {
|
||||||
|
repl = QString::number(QDate::currentDate().year());
|
||||||
|
}
|
||||||
|
s.replace(i, 4, repl);
|
||||||
|
}
|
||||||
|
|
||||||
|
i = s.indexOf("YY");
|
||||||
|
if (i != -1) {
|
||||||
|
// 以像素宽度为准,'88' 通常足够宽
|
||||||
|
s.replace(i, 2, QString("88"));
|
||||||
|
}
|
||||||
|
|
||||||
|
i = s.indexOf("MM");
|
||||||
|
if (i != -1) {
|
||||||
|
s.replace(i, 2, longestFromList(model.monthsMap, QString("88")));
|
||||||
|
}
|
||||||
|
|
||||||
|
i = s.indexOf("dd");
|
||||||
|
if (i != -1) {
|
||||||
|
s.replace(i, 2, longestFromList(model.daysMap, QString("88")));
|
||||||
|
}
|
||||||
|
|
||||||
|
i = s.indexOf("HH");
|
||||||
|
if (i != -1) {
|
||||||
|
s.replace(i, 2, longestFromList(model.hoursMap, QString("88")));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp minutePattern("mm");
|
||||||
|
if (s.contains(minutePattern)) s.replace(minutePattern, QString("88"));
|
||||||
|
|
||||||
|
QRegExp secondPattern("ss");
|
||||||
|
if (s.contains(secondPattern)) s.replace(secondPattern, QString("88"));
|
||||||
|
|
||||||
|
i = s.indexOf("w");
|
||||||
|
if (i != -1) {
|
||||||
|
s.replace(i, 1, longestFromList(model.weeksMap, QString("888")));
|
||||||
|
}
|
||||||
|
|
||||||
|
QRegExp weekNumberPattern("c");
|
||||||
|
if (s.contains(weekNumberPattern)) s.replace(weekNumberPattern, QString("88"));
|
||||||
|
|
||||||
|
return s;
|
||||||
|
}
|
||||||
|
|
||||||
PicDateItem::PicDateItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
|
PicDateItem::PicDateItem(QGraphicsItem *parent, QGraphicsScene *scene, const SourceType type)
|
||||||
:PicTextItem(parent, scene, type)
|
:PicTextItem(parent, scene, type)
|
||||||
{
|
{
|
||||||
@@ -33,6 +104,27 @@ void PicDateItem::setSource(QVariant var)
|
|||||||
void PicDateItem::setModel(DateItemModel model)
|
void PicDateItem::setModel(DateItemModel model)
|
||||||
{
|
{
|
||||||
m_model = std::move(model);
|
m_model = std::move(model);
|
||||||
|
|
||||||
|
// 计时:测量生成最长字符串和字体度量两段耗时
|
||||||
|
QElapsedTimer t1;
|
||||||
|
t1.start();
|
||||||
|
m_maxDateTimeStr = generateMaxDateTimeString(m_model, font());
|
||||||
|
qint64 genUs = t1.nsecsElapsed() / 1000; // microseconds
|
||||||
|
|
||||||
|
QElapsedTimer t2;
|
||||||
|
t2.start();
|
||||||
|
if (m_maxDateTimeStr.isEmpty()) {
|
||||||
|
m_maxSize = QSize();
|
||||||
|
} else {
|
||||||
|
QFontMetrics fm(font());
|
||||||
|
int w = fm.horizontalAdvance(m_maxDateTimeStr);
|
||||||
|
int h = fm.height();
|
||||||
|
m_maxSize = QSize(w, h);
|
||||||
|
}
|
||||||
|
qint64 fmUs = t2.nsecsElapsed() / 1000; // microseconds
|
||||||
|
|
||||||
|
qDebug() << "PicDateItem::setModel timing(us): generate=" << genUs << ", fm=" << fmUs << ", total=" << (genUs + fmUs);
|
||||||
|
|
||||||
setSource(m_model.datetimePattern);
|
setSource(m_model.datetimePattern);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -84,6 +176,38 @@ QImage PicDateItem::itemImage()
|
|||||||
if(m_model.datetimePattern.isEmpty())
|
if(m_model.datetimePattern.isEmpty())
|
||||||
return QImage();
|
return QImage();
|
||||||
|
|
||||||
auto ret = strToImage(m_currDateTimeStr);
|
auto currImg = strToImage(m_currDateTimeStr);
|
||||||
return ret;
|
|
||||||
|
if (m_maxSize.isEmpty())
|
||||||
|
return currImg;
|
||||||
|
|
||||||
|
int width = qMax(currImg.width(), m_maxSize.width());
|
||||||
|
int height = qMax(currImg.height(), m_maxSize.height());
|
||||||
|
|
||||||
|
QImage img(width, height, QImage::Format_ARGB32);
|
||||||
|
img.fill(QColor(0,0,0,0).rgba());
|
||||||
|
|
||||||
|
QPainter painter(&img);
|
||||||
|
int y = (height - currImg.height()) / 2;
|
||||||
|
painter.drawImage(0, y, currImg);
|
||||||
|
painter.end();
|
||||||
|
|
||||||
|
return img;
|
||||||
|
}
|
||||||
|
|
||||||
|
QRectF PicDateItem::boundingRect() const
|
||||||
|
{
|
||||||
|
// 优先使用已经应用变换后的 m_itemImage(与 PicTextItem 保持一致)
|
||||||
|
if (!m_itemImage.isNull()) {
|
||||||
|
return QRectF(0, 0, m_itemImage.width(), m_itemImage.height());
|
||||||
|
}
|
||||||
|
|
||||||
|
// 否则基于缓存的最大像素尺寸和粗体倍数估算
|
||||||
|
int w = m_maxSize.width();
|
||||||
|
int h = m_maxSize.height();
|
||||||
|
if (w <= 0 || h <= 0)
|
||||||
|
return QGraphicsTextItem::boundingRect();
|
||||||
|
|
||||||
|
qreal bw = qreal(w) * qMax(1, m_boldMultiple);
|
||||||
|
return QRectF(0, 0, bw, qreal(h));
|
||||||
}
|
}
|
||||||
@@ -35,6 +35,10 @@ private:
|
|||||||
|
|
||||||
DateItemModel m_model;
|
DateItemModel m_model;
|
||||||
QString m_currDateTimeStr;
|
QString m_currDateTimeStr;
|
||||||
|
QString m_maxDateTimeStr;
|
||||||
|
QSize m_maxSize; // 缓存最长字符串的像素宽高
|
||||||
|
|
||||||
|
virtual QRectF boundingRect() const override;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // PIC_DATE_ITEM_H
|
#endif // PIC_DATE_ITEM_H
|
||||||
|
|||||||
Reference in New Issue
Block a user