我有一个标尺类(称为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 ... */
}
}
Run Code Online (Sandbox Code Playgroud)
下面是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]);
}
Run Code Online (Sandbox Code Playgroud)
我想知道我是否可以避免这些条件检查可能数千次.我对可以使用哪种代码模式感兴趣(尽管最好只计算一次行位置并仅绘制可见的内容).
好的,在您发布该图像后,看起来您可以找到更简单有效的解决方案.
你的线条形成了一个可重复的模式,因此,绘制整个事物,手动管理线条以及诸如此类的东西将是一种浪费.您可以创建一个小像素图,并只绘制重复模式的一个部分,如下所示:

然后根据方向,您可以保持原样或旋转/翻转它.然后,您可以使用它QPainter来填充您的Graduation小部件,它将Qt::TexturePattern使用模式QBrush::setTexture(pixmap)快速有效地填充整个小部件长度/高度,无论它是多少.
如果要更改标尺的样式或间距,您只需重新绘制缓存的图案并使用相同的过程更新标尺.
最后但并非最不重要的是,您可以使用Qt提供的布局将标尺捕捉到正确的位置,以便100%自动管理它们,使您当前使用的逻辑变得多余.
好的,这里有一点帮助,另外这将告诉你你不必每行都画线,代码很简单并且会为给定的DPI生成模式段:
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;
}
Run Code Online (Sandbox Code Playgroud)
您可能会注意到典型的低DPI台式机显示器上的线路有些模糊,但这是您为"物理上准确"而付出的代价 - 您要么是公制完美的还是像素完美的,除非您的DPI与公制单位匹配,否则您不能同时使用这两者完美地说,大多数线条都必然发生在像素之间.在高DPI移动设备上,它看起来不会那么糟糕.
或者,如果省略HighQualityAntialiasing,则可以获得清晰的线条,但这些线条的距离不会相等.不过,这可能对你有好处,因为对于像Photoshop这样的商业软件来说它显然已经足够了:

然而,PS是棘手的并且在1厘米内具有较少的线,因此差异不像每毫米线具有的那样显着.以下是我的108.79 DPI桌面上的代码结果:
