4

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

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

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

在此处输入图像描述

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

  1. 在鼠标下获取颜色
  2. 根据颜色,洪水填充孔。(不同的孔用颜色区分)
  3. 鼠标移出时,恢复颜色。会有电线穿过孔,所以我不能只更新小矩形(孔)。

最快的方法是什么?我提取颜色的尝试不起作用,即上面代码中的消息框永远不会显示。此外,我怀疑我现有的代码是否足够快以满足我的目的。请记住,在面包板上移动鼠标的速度有多快。

注意 - 我可以使用 wxWidgets 框架来做到这一点。但由于一些问题,该项目停滞不前。我现在正在使用 Qt 重写它。
邀请您查看代码https://github.com/vinayak-garg/dic-sim

4

2 回答 2

5

在 Qt 中执行此操作的“惯用”方式与您所描述的完全不同。你会为这类事情使用图形视图框架。

图形视图提供了一个用于管理大量定制 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();
}

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

于 2012-10-27T07:49:22.937 回答
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 的答案会更好。

于 2012-10-27T07:57:20.873 回答