I am writing an image processing application in Qt5. The imagery is natievly 16-bit colordepth, and needs to be adjusted to 8-bit for display.

In the normal case, I analyze the data currently visible in the QGraphicsView and create a dynamic map to optimally display those pixels. This is done every time the viewport moves in any way. This map is associated with the QGraphicsView.

I've subclassed QGraphicsScene, QGraphicsView, and QGraphicsPixmapItem along the way.

My first attempt was to update the QGraphicsPixmapItem's pixmap whenever the histogram got recalculated, but that doesn't work because the QGraphicsPixmapItem might be visible in several views... there is no way to access the view normally.

My second attempt was to override the QGraphicPixmapItem's paint method, which does know which view it is painting on, and apply the map then (similar to what QTransform does, really, except in colorspace). However, updating the pixmap forces an update, so doing it inside the paint method would produce constant painting.

My third attempt was to rip the setPixmap function out of the QGraphicsPixmapItem and implement a version without the update to use right before painting, but of course it accesses private members that I can't in a subclass.

The remaining options I can foresee are all undesireable:

  1. Modify QT so that QTransform supports colarspace manipulation (too much work and I really want a stock QT)
  2. Copy the code for QGraphicsPixmapItem instead of subclassing it, and make it work the way I want (probably a license issue)
  3. Assume I've only got the one view and just hack it in somewhere.

Am I going about this the entirely wrong way? Is there a QT feature I'm not using?

有帮助吗?

解决方案

I can suggest the following way.

Don't use QGraphicsPixmapItem. It doesn't really fits for your goal. Create a subclass of QGraphicsItem and perform the painting manually. Enable the QGraphicsItem::ItemUsesExtendedStyleOption flag for the item so that QStyleOptionGraphicsItem::exposedRect passed to the paint method is real exposed rectangle. Set the view's viewportUpdateMode to QGraphicsView::FullViewportUpdate. The view will repaint all viewport any time a scroll is moved and call paint method of visible graphics item. In the paint method implementation you can do any logic you wish. For example, you can construct new QPixmap object (or update existing one) and paint it using QPainter::drawPixmap.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top