What is the fastest way to get the color of a QWidget pixel under a mouse?

I need to get the color of the pixel under the mouse, inside the mouseMoveEvent QWidget (Layout). I currently have this code →

 void Breadboard::mouseMoveEvent(QMouseEvent *e) { QPixmap pixmap = QPixmap::grabWindow(winId()); QRgb color = pixmap.toImage().pixel(e->x(), e->y()); if (QColor(color) == terminalColor) QMessageBox::information(this, "Ter", "minal"); } 

See screenshot (reduced) below -

enter image description here

When the user moves the mouse to the layout, the hole should be highlighted in a different color (for example, in a red circle). And when the mouse exits, the previous color (gray) should be restored. Therefore, I need to take the following steps:

  • Get color under the mouse
  • According to the color, fill the hole. (Various holes are highlighted in color)
  • Mouse over to restore color. There will be wires passing through the holes, so I can’t update just a small rectangle (hole).

What is the fastest way to do this? My attempt to extract color does not work, because the Message field in my previous code is never displayed. Moreover, I doubt that my existing code is fast enough for my purpose. Remember how fast you will move the mouse to the layout.

Note. I was able to do this using the wxWidgets framework. But due to some problems that the project stalled. And I'm rewriting it with Qt now. You are invited to see the code https://github.com/vinayak-garg/dic-sim

+4
source share
2 answers

The “idiomatic” way to do this in Qt is completely different from what you are describing. You are using the Graphics View Framework for this type of thing.

The graphic view provides a surface for managing and interacting with a large number of customizable 2D graphic elements and a view widget for visualizing elements with support for scaling and rotation.

You define your own QGraphicsItem type for the "cells" in the layout, which will respond to freeze input / stop events by changing their color. Connections between cells (wires, resistors, etc.) will also have their own types of graphic elements with the functions you need for them.

Here's a quick and dirty example. It creates a grid of green 50 × 50 cells that turn red when the mouse is over them.

 #include <QtGui> class MyRect: public QGraphicsRectItem { public: MyRect(qreal x, qreal y, qreal w, qreal h) : QGraphicsRectItem(x,y,w,h) { setAcceptHoverEvents(true); setBrush(Qt::green); } protected: void hoverEnterEvent(QGraphicsSceneHoverEvent *) { setBrush(Qt::red); update(); } void hoverLeaveEvent(QGraphicsSceneHoverEvent *) { setBrush(Qt::green); update(); } }; int main(int argc, char **argv) { QApplication app(argc, argv); QGraphicsScene scene; for (int i=0; i<50; i++) for (int j=0; j<50; j++) scene.addItem(new MyRect(10*i, 10*j, 8, 8)); QGraphicsView view(&scene); view.show(); return app.exec(); } 

You can change the hover event handlers to talk to your “main window” or “controller” indicating what is currently under the mouse so that you can update the title, legend box, or tool palette.

+5
source

For best speed, visualize only the part of the widget that you are interested in in QPaintDevice (for example, QPixmap). Try something like this:

 void Breadboard::mouseMoveEvent(QMouseEvent *e) { // Just 1 pixel. QPixmap pixmap(1, 1); // Target coordinates inside the pixmap where drawing should start. QPoint targetPos(0, 0); // Source area inside the widget that should be rendered. QRegion sourceArea( /* use appropriate coordinates from the mouse event */ ); // Render it. this->render(&pixmap, targetPos, sourceArea, /* look into what flags you need */); // Do whatever else you need to extract the color from the 1 pixel pixmap. } 

The mat answer is better if you want to reorganize the application to use the graphical presentation API.

+2
source

Source: https://habr.com/ru/post/1442452/


All Articles