在鼠标下获取QWidget像素颜色的最快方法是什么?

时间:2012-10-27 07:28:57

标签: c++ qt qt4.8

我需要在QWidget(面包板)的mouseMoveEvent内获取鼠标下的像素颜色。目前我有这个代码 - >

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");
}

看看下面的(按比例缩小)截图 -

enter image description here

当用户将鼠标移动到面包板上时,该孔应突出显示一些不同的颜色(如红色圆圈)。当鼠标退出时,应恢复之前的颜色(灰色)。所以我需要做以下步骤 -

  1. 在鼠标下获取颜色
  2. 根据颜色,填充洞。 (使用颜色区分不同的孔)
  3. 在鼠标移出时,恢复颜色。会有电线穿过孔,所以我不能只更新小矩形(孔)。
  4. 这样做的最快方法是什么?我提取颜色的尝试不起作用,即上面代码中的消息框永远不会显示。此外,我怀疑我的现有代码是否足够快我的目的。请记住,将鼠标放在面包板上的速度有多快。

    注意 - 我能够使用wxWidgets框架执行此操作。但由于项目陷入停滞的一些问题。我现在用Qt重写它。
    邀请您查看代码https://github.com/vinayak-garg/dic-sim

2 个答案:

答案 0 :(得分:5)

在Qt中执行此操作的“惯用”方式与您所描述的完全不同。您可以将Graphics View Framework用于此类事情。

  

图形视图提供了一个表面,用于管理和交互大量自定义的2D图形项目,以及一个用于可视化项目的视图窗口小部件,支持缩放和旋转。

您可以为面包板中的“单元格”定义自己的QGraphicsItem类型,以便通过更改颜色来对悬停进入/离开事件作出反应。单元(电线,电阻器等)之间的连接也有自己的图形项类型,具有您需要的功能。

这是一个快速而又肮脏的例子。它产生一个50x50的绿色网格网格,当鼠标悬停在它们上面时会变成红色。

#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();
}

您可以修改悬停事件处理程序,以便与“主窗口”或“控制器”对话,指示当前鼠标下方的内容,以便更新标题,图例框或工具调色板。

答案 1 :(得分:2)

为获得最佳速度,只将您感兴趣的小部件部分渲染到QPaintDevice(如QPixmap)。尝试这样的事情:

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.
}

如果您愿意重构您的应用程序以使用图形视图API,那么Mat的答案会更好。