2012-10-27 54 views
4

我需要在QWidget(麪包板)的mouseMoveEvent內獲得鼠標下像素的顏色。目前,我有這樣的代碼 - >什麼是在鼠標下獲得QWidget像素顏色的最快方法?

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. 根據顏色,floodfill孔。 (使用顏色區分不同的孔)
  3. 在鼠標移出時,恢復顏色。將有電線穿過孔,所以我不能只更新小矩形(孔)。

這樣做的最快方法是什麼?我嘗試提取顏色不起作用,即我上面的代碼中的消息框從不顯示。此外,我懷疑我的現有代碼是否足夠滿足我的目的。請記住,您將在麪包板上移動鼠標的速度有多快。

注 - 我能夠使用wxWidgets框架來做到這一點。但是由於一些項目停滯不前的問題。我現在正在使用Qt重寫它。
您被邀請查看代碼https://github.com/vinayak-garg/dic-sim

回答

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

您可以修改懸停事件處理程序跟你的「主窗口」或「控制器」,表示目前有什麼鼠標下,因此您可以更新您的標題,圖例框或工具選項板。

+0

+1謝謝!那麼我可以將'Breadboard'作爲'QGraphicsScene'對象而不是將它變成'QWidget'嗎? –

+0

是的,這聽起來像一個選項。爲「細胞」/洞洞建立一個自定義類,如果你需要自定義行爲,則爲「壩」/線創建一個自定義類。然後將它們添加到您的麪包板場景。 (這一切都非常快,即使在場景中有大量物品。) – Mat

+0

這正是我所需要的。謝謝! –

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的答案會更好。

相關問題