2

我已经使用 Qt4 实现了一个选取框文本小部件。我首先将文本内容绘制到像素图上。然后通过调用painter.drawTiledPixmap(offsetX, offsetY, myPixmap) 将此像素图的一部分绘制到绘制设备上

我的想象是,Qt 将用来自 myPixmap 的内容填充整个选取框文本矩形。

有没有更快的方法,将所有现有内容向左移动 1px,而不是用来自 myPixmap 的内容填充新暴露的 1px 宽和 N-px 高的区域?

4

4 回答 4

1

问候,

实现这一目标的一种可能性是:

  1. 创建一个 QGraphicsScene + View 并将像素图放在上面两次(作为 QGraphicsPixmapItem),因此它们彼此相邻。
  2. 调整视图大小以适合(一个)像素图的大小。
  3. 然后,无需重新绘制像素图,您只需重新定位视图的视口,从一个像素图移动到下一个像素图。
  4. 在最后跳回来创建循环。

这可能会也可能不会更快(就性能而言) - 我没有测试过。但如果只是为了实验,可能值得一试。

于 2010-04-26T12:54:57.743 回答
1

由于您使用低级绘画方法,因此您的方法可能是最快的方法之一。您可以在低级绘画和QGraphicsScene选项之间实现一种中间方法:使用包含标签的滚动区域。

下面是一个创建包含文本标签的新滚动区域的代码示例。您可以使用 a 自动滚动标签QTimer以触发滚动效果,这为您提供了一个不错的选取框小部件。

QScrollArea *scrollArea = new QScrollArea();

// ensure that scroll bars never show
scrollArea->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
scrollArea->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

QLabel *label = new QLabel("your scrolling text");

// resize the scroll area : 50px length and an height equals to its content height.
scrollArea->resize(50, label->size().height());
scrollArea->setWidget(label);
label->show(); // optionnal if the scroll area is not yet visible

QScrollArea::scrollContentsBy(int dx, int dy)滚动区域内的文本标签可以使用参数从左到右移动一个像素dx等于-1

于 2010-05-05T12:03:12.863 回答
1

好。这是我过去用较慢的硬件做的一个技巧。基本上,图像缓冲区分配的宽度是需要的两倍,开头有 1 行。在缓冲区的左侧构建图像。然后在缓冲区中一次推进 1 个像素的情况下重复绘制图像。

int w = 200;
int h = 100;
int rowBytes = w * sizeof(QRgb) * 2; // line buffer is twice as the width
QByteArray buffer(rowBytes * (h + 1), 0xFF); // 1 more line than the height
uchar * p = (uchar*)buffer.data() + rowBytes; // start drawing the image content at 2nd line
QImage image(p, w, h, rowBytes, QImage::Format_RGB32); // 1st line is used as the padding at the start of scroll
image.fill(qRgb(255, 0, 0)); // well. do something to the image

p = image.bits() - rowBytes / 2; //  start scrolling at the middle of the 1st (blank) line
for(int i=0;i<w;++i, p+=sizeof(QRgb)) {
    QImage  scroll(p, w, h, rowBytes, QImage::Format_RGB32); // scrool 1 pixel at a time
    scroll.save(QString("%1.png").arg(i));
}

我不确定这会比仅仅改变图像的偏移量并画出它更快。今天的硬件非常强大,这使得许多旧技巧变得无用。但是玩不起眼的把戏很有趣。:)

于 2010-05-08T20:00:37.233 回答
0

为什么不逐个像素地做呢?由于缓存的工作方式,一直将像素写入它之前的像素,直到你到达终点。然后,您可以通过读取其他图像来填充最后一列。

然后 SIMD 也很容易对其进行优化;尽管此时您开始进入每个平台的优化。

于 2010-05-11T17:52:37.810 回答