我有一个标尺类(称为Graduation
),它使用方向来计算应绘制线的位置。像这样:
当方向设置为Qt::Horizontal
时,我会line_xpos = precendent_line_xpos + number
。然后,如果方向是Qt::Vertical
,我会添加到y位置。
我在下面有一些代码,这是我如何使用if...else
和?:
语句执行此操作的示例:
/* std::vector<QLineF> m_lines; */
void Graduation::resizeEvent(QResizeEvent *event)
{
qreal newLength = (m_orientation == Qt::Horizontal)
? event->size().width()
: event->size().height();
qreal oldLength = (m_orientation == Qt::Horizontal)
? event->oldSize().width()
: event->oldSize().height();
if(newLength != oldLength) {
if(newLength < oldLength) { /* Delete lines */
int count = m_lines.size();
if(count == 0)
return;
if(m_orientation == Qt::Horizontal) {
while(m_lines[count-1].x1() > newLength) {
--count;
}
} else {
while(m_lines[count-1].y1() > newLength) {
--count;
}
}
m_lines.erase(
m_lines.begin()+count,
m_lines.begin()+m_lines.size()
);
} else
/* ... Append lines ... */
}
}
这是paintEvent,用于显示如何绘制线条:
void Graduation::paintEvent(QPaintEvent *event)
{
Q_UNUSED(event)
QPainter painter(this);
painter.setPen(QPen(Qt::black, 0.5));
for(unsigned int i = 0; i < m_lines.size(); ++i)
painter.drawLine(m_lines[i]);
}
我想知道我是否可以避免这些条件被检查数千次。我对可以用来避免的代码模式感兴趣(尽管最好只计算一次行位置并只绘制可见的内容)。
答案 0 :(得分:8)
好的,在您发布该图片后,看起来您可以找到更简单有效的解决方案。
你的线条形成了一个可重复的模式,因此,绘制整个事物,手动管理线条以及诸如此类的东西将是一种浪费。您可以创建一个小像素图并仅绘制重复图案的一个部分,如下所示:
然后根据方向,您可以保持原样或旋转/翻转它。然后,您可以使用QPainter
使用Graduation
Qt::TexturePattern
使用QBrush::setTexture(pixmap)
填充QPixmap drawCMPattern(qreal dpi) {
qreal dpcm = dpi / 2.54;
QPixmap rulerCache(dpcm, dpcm / 2);
rulerCache.fill();
qreal dpmm = dpcm / 10;
QPainter p(&rulerCache);
p.setRenderHint(QPainter::HighQualityAntialiasing);
qreal lineWidth = dpmm / 5;
p.setPen(QPen(Qt::black, lineWidth));
qreal xpos = lineWidth / 2;
for (int i = 0; i < 10; ++i) {
if (i == 0) p.drawLine(QLineF(xpos, 0, xpos, rulerCache.height()));
else if (i == 5) p.drawLine(QLineF(xpos, 0, xpos, rulerCache.height() / 2));
else p.drawLine(QLineF(xpos, 0, xpos, rulerCache.height() / 4));
xpos += dpmm;
}
return rulerCache;
}
窗口小部件,它将使用模式快速有效地填充整个窗口小部件长度/高度这是多少。
如果要更改标尺的样式或间距,您只需重绘缓存的图案并使用相同的过程更新标尺。
最后但并非最不重要的是,您可以使用Qt提供的布局将标尺捕捉到正确的位置,以便100%自动管理它们,使您当前使用的逻辑变得多余。
好的,这里有一点帮助,另外这将告诉你,你不必每行都有画线,代码很简单,并且会为给定的DPI生成模式片段:
HighQualityAntialiasing
您可能会注意到典型的低DPI台式机显示器上的线条有些模糊,但这是您为物理上的准确而付出的代价&#34; - 你要么是公制完美的,要么像素完美,除非你的DPI与公制单位完美匹配,否则大多数线都必然会出现在像素之间。在高DPI移动设备上,它看起来不会那么糟糕。
或者,如果省略{{1}},则可以获得清晰的线条,但这些线条的距离不会相等。尽管如此,这可能对你有好处,因为对于像Photoshop这样的商业软件来说它显然已经足够了:
然而,PS是棘手的并且在1厘米处具有较少的线,因此差异不像每毫米线具有的那样显着。以下是我的108.79 DPI桌面上代码结果的显示方式: