From 5cbe64dac73083b1c65916a69075735804d23d06 Mon Sep 17 00:00:00 2001 From: Yannick Verdie <no@email> Date: Sat, 19 Jun 2010 18:57:04 +0000 Subject: [PATCH] New functions with QT GUI Shortcut for zoom (CTRL + and CTRL - for zoomin/out, CTRL Left/Right/Up/Down for panning, CTRL P for zoom = 1) Fix bug with key event --- modules/highgui/src/window_QT.cpp | 136 ++++++++++++++++++++++----- modules/highgui/src/window_QT.h | 151 +++++++++++++++++------------- 2 files changed, 198 insertions(+), 89 deletions(-) diff --git a/modules/highgui/src/window_QT.cpp b/modules/highgui/src/window_QT.cpp index 89ae871ad5..8b41792c12 100755 --- a/modules/highgui/src/window_QT.cpp +++ b/modules/highgui/src/window_QT.cpp @@ -630,7 +630,6 @@ int GuiReceiver::start() CvTrackbar::CvTrackbar(CvWindow* arg, QString name, int* value, int count, CvTrackbarCallback on_change ) { - //moveToThread(qApp->instance()->thread()); setObjectName(trackbar_name); parent = arg; trackbar_name = name; @@ -638,7 +637,6 @@ CvTrackbar::CvTrackbar(CvWindow* arg, QString name, int* value, int count, CvTra callback = on_change; slider = new QSlider(Qt::Horizontal); - //slider->setObjectName(trackbar_name); slider->setFocusPolicy(Qt::StrongFocus); slider->setMinimum(0); slider->setMaximum(count); @@ -742,10 +740,27 @@ CvWindow::CvWindow(QString arg, int arg2) myview = new ViewPort(this, CV_MODE_NORMAL); myview->setAlignment(Qt::AlignHCenter); + + shortcutZ = new QShortcut(Qt::CTRL + Qt::Key_P, this); + QObject::connect( shortcutZ, SIGNAL( activated ()),myview, SLOT( resetZoom( ) )); + shortcutPlus = new QShortcut(QKeySequence(QKeySequence::ZoomIn), this); + QObject::connect( shortcutPlus, SIGNAL( activated ()),myview, SLOT( ZoomIn() )); + shortcutMinus = new QShortcut(QKeySequence(QKeySequence::ZoomOut), this); + QObject::connect(shortcutMinus, SIGNAL( activated ()),myview, SLOT( ZoomOut() )); + shortcutLeft = new QShortcut(Qt::CTRL + Qt::Key_Left, this); + QObject::connect( shortcutLeft, SIGNAL( activated ()),myview, SLOT( siftWindowOnLeft() )); + shortcutRight = new QShortcut(Qt::CTRL + Qt::Key_Right, this); + QObject::connect( shortcutRight, SIGNAL( activated ()),myview, SLOT( siftWindowOnRight() )); + shortcutUp = new QShortcut(Qt::CTRL + Qt::Key_Up, this); + QObject::connect(shortcutUp, SIGNAL( activated ()),myview, SLOT( siftWindowOnUp() )); + shortcutDown = new QShortcut(Qt::CTRL + Qt::Key_Down, this); + QObject::connect(shortcutDown, SIGNAL( activated ()),myview, SLOT( siftWindowOnDown() )); + layout = new QBoxLayout(QBoxLayout::TopToBottom); layout->setSpacing(5); layout->setObjectName(QString::fromUtf8("boxLayout")); layout->setContentsMargins(0, 0, 0, 0); + layout->setMargin(0); layout->addWidget(myview); if (flags == CV_WINDOW_AUTOSIZE) @@ -792,12 +807,37 @@ void CvWindow::addSlider(QString name, int* value, int count,CvTrackbarCallback layout->insertLayout(layout->count()-1,t); } +//Need more test here ! void CvWindow::keyPressEvent(QKeyEvent *event) { - mutexKey.lock(); - last_key = (int)event->text().toLocal8Bit().at(0); - mutexKey.unlock(); - key_pressed.wakeAll(); + //see http://doc.trolltech.com/4.6/qt.html#Key-enum + int key = event->key(); + bool goodKey = false; + + if (key>=20 && key<=255 ) + { + key = (int)event->text().toLocal8Bit().at(0); + goodKey = true; + } + + if (key == Qt::Key_Escape) + { + key = 27; + goodKey = true; + } + + //control plus Z, plus +, and plus - are used for zoom functions + if (event->modifiers() != Qt::ControlModifier && goodKey) + { + mutexKey.lock(); + last_key = key; + + //last_key = event->nativeVirtualKey (); + mutexKey.unlock(); + key_pressed.wakeAll(); + //event->accept(); + } + QWidget::keyPressEvent(event); } @@ -823,8 +863,10 @@ ViewPort::ViewPort(QWidget* arg, int arg2) { mode = arg2; centralWidget = arg, + setupViewport(centralWidget); - setUpdatesEnabled(true); + setContentsMargins(0,0,0,0); + setObjectName(QString::fromUtf8("graphicsView")); timerDisplay = new QTimer(this); timerDisplay->setSingleShot(true); @@ -833,21 +875,20 @@ ViewPort::ViewPort(QWidget* arg, int arg2) positionGrabbing = QPointF(0,0); positionCorners = QRect(0,0,size().width(),size().height()); + + + +#if defined(OPENCV_GL) if (mode == CV_MODE_OPENGL) { -#if defined(OPENCV_GL) setViewport(new QGLWidget(QGLFormat(QGL::SampleBuffers))); initGL(); -#endif } +#endif image2Draw=cvCreateImage(cvSize(centralWidget->width(),centralWidget->height()),IPL_DEPTH_8U,3); cvZero(image2Draw); - - setSceneRect(0,0,size().width(),size().height()); - this->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - this->setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff); - this->setInteractive(false); + setInteractive(false); } ViewPort::~ViewPort() @@ -858,6 +899,51 @@ ViewPort::~ViewPort() delete timerDisplay; } +void ViewPort::resetZoom() +{ + matrixWorld.reset(); + controlImagePosition(); +} + +void ViewPort::ZoomIn() +{ + scaleView( 0.5,QPointF(size().width()/2,size().height()/2)); +} + +void ViewPort::ZoomOut() +{ + scaleView( -0.5,QPointF(size().width()/2,size().height()/2)); +} + + +//Note: move 2 percent of the window +void ViewPort::siftWindowOnLeft() +{ + float delta = 2*width()/(100.0*matrixWorld.m11()); + moveView(QPointF(delta,0)); +} + +//Note: move 2 percent of the window +void ViewPort::siftWindowOnRight() +{ + float delta = -2*width()/(100.0*matrixWorld.m11()); + moveView(QPointF(delta,0)); +} + +//Note: move 2 percent of the window +void ViewPort::siftWindowOnUp() +{ + float delta = 2*height()/(100.0*matrixWorld.m11()); + moveView(QPointF(0,delta)); +} + +//Note: move 2 percent of the window +void ViewPort::siftWindowOnDown() +{ + float delta = -2*height()/(100.0*matrixWorld.m11()); + moveView(QPointF(0,delta)); +} + void ViewPort::startDisplayInfo(QString text, int delayms) { if (timerDisplay->isActive()) @@ -939,8 +1025,18 @@ void ViewPort::controlImagePosition() //save also the inv matrix matrixWorld_inv = matrixWorld.inverted(); + + + viewport()->update(); } +void ViewPort::moveView(QPointF delta) +{ + matrixWorld.translate(delta.x(),delta.y()); + controlImagePosition(); +} + +//factor is -0.5 (zoom out) or 0.5 (zoom in) void ViewPort::scaleView(qreal factor,QPointF center) { factor/=5;//-0.1 <-> 0.1 @@ -965,8 +1061,6 @@ void ViewPort::scaleView(qreal factor,QPointF center) setCursor(Qt::OpenHandCursor); else unsetCursor(); - - viewport()->update(); } void ViewPort::wheelEvent(QWheelEvent *event) @@ -1184,8 +1278,7 @@ void ViewPort::mouseMoveEvent(QMouseEvent *event) positionGrabbing = event->pos(); - matrixWorld.translate(dxy.x(),dxy.y()); - controlImagePosition(); + moveView(dxy); } QWidget::mouseMoveEvent(event); @@ -1204,8 +1297,8 @@ QSize ViewPort::sizeHint() const void ViewPort::resizeEvent ( QResizeEvent *event) { - controlImagePosition(); - return QGraphicsView::resizeEvent(event); + controlImagePosition(); + return QGraphicsView::resizeEvent(event); } @@ -1258,7 +1351,7 @@ void ViewPort::drawOverview(QPainter *painter) const int margin = 5; - painter->setBrush(QBrush ( QColor(0, 0, 0, 127))); + painter->setBrush(QColor(0, 0, 0, 127)); painter->setPen(Qt::darkGreen); painter->drawRect(QRect(width()-viewSize.width()-margin, 0,viewSize.width(),viewSize.height())); @@ -1266,7 +1359,6 @@ void ViewPort::drawOverview(QPainter *painter) qreal ratioSize = 1/matrixWorld.m11(); qreal ratioWindow = (qreal)(viewSize.height())/(qreal)(size().height()); - painter->setBrush(QColor(0, 0, 0, 127)); painter->setPen(Qt::darkBlue); painter->drawRect(QRectF(width()-viewSize.width()-positionCorners.left()*ratioSize*ratioWindow-margin, -positionCorners.top()*ratioSize*ratioWindow, diff --git a/modules/highgui/src/window_QT.h b/modules/highgui/src/window_QT.h index 4db7aa112c..d62b623cc4 100644 --- a/modules/highgui/src/window_QT.h +++ b/modules/highgui/src/window_QT.h @@ -65,6 +65,7 @@ #include <QSlider> #include <QLabel> #include <QIODevice> +#include <QShortcut> //Macro here #define CV_MODE_NORMAL 0 @@ -83,7 +84,7 @@ public: GuiReceiver(); int start(); bool _bTimeOut; - + private: @@ -124,7 +125,7 @@ private: QString createLabel(); QPointer<QPushButton > label; CvTrackbarCallback callback; - CvWindow* parent; + QPointer<CvWindow> parent; int* dataSlider; }; @@ -151,9 +152,15 @@ protected: private: QPointer<ViewPort> myview; - - int status;//0 normal, 1 fullscreen (YV) + int status;//0 normal, 1 fullscreen (YV) + QPointer<QShortcut> shortcutZ; + QPointer<QShortcut> shortcutPlus; + QPointer<QShortcut> shortcutMinus; + QPointer<QShortcut> shortcutLeft; + QPointer<QShortcut> shortcutRight; + QPointer<QShortcut> shortcutUp; + QPointer<QShortcut> shortcutDown; }; @@ -166,30 +173,41 @@ public: ~ViewPort(); void updateImage(void* arr); void startDisplayInfo(QString text, int delayms); - void setMouseCallBack(CvMouseCallback m, void* param); + void setMouseCallBack(CvMouseCallback m, void* param); public slots: //reference: //http://www.qtcentre.org/wiki/index.php?title=QGraphicsView:_Smooth_Panning_and_Zooming //http://doc.qt.nokia.com/4.6/gestures-imagegestures-imagewidget-cpp.html void scaleView(qreal scaleFactor, QPointF center); + void moveView(QPointF delta); + void resetZoom(); + void ZoomIn(); + void ZoomOut(); + void siftWindowOnLeft(); + void siftWindowOnRight(); + void siftWindowOnUp() ; + void siftWindowOnDown(); void resizeEvent ( QResizeEvent * ); private: + QGraphicsScene *myScene; + QPointF positionGrabbing; QRect positionCorners; QTransform matrixWorld; QTransform matrixWorld_inv; - - CvMouseCallback on_mouse; + + CvMouseCallback on_mouse; void* on_mouse_param; int mode; IplImage* image2Draw; + bool isSameSize(IplImage* img1,IplImage* img2); QSize sizeHint() const; - QWidget* centralWidget; - QTimer* timerDisplay; + QPointer<QWidget> centralWidget; + QPointer<QTimer> timerDisplay; bool drawInfo; QString infoText; //QImage* image; @@ -201,10 +219,9 @@ private: void mouseReleaseEvent(QMouseEvent *event); void mouseDoubleClickEvent(QMouseEvent *event); void drawInstructions(QPainter *painter); + void drawOverview(QPainter *painter); void draw2D(QPainter *painter); void controlImagePosition(); - void drawOverview(QPainter *painter); - #if defined(OPENCV_GL) void draw3D(); @@ -221,61 +238,61 @@ private slots: //here css for trackbar /* from http://thesmithfam.org/blog/2010/03/10/fancy-qslider-stylesheet */ static const QString str_Trackbar_css = QString("") -+ "QSlider::groove:horizontal {" -+ "border: 1px solid #bbb;" -+ "background: white;" -+ "height: 10px;" -+ "border-radius: 4px;" -+ "}" - -+ "QSlider::sub-page:horizontal {" -+ "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," -+ "stop: 0 #66e, stop: 1 #bbf);" -+ "background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1," -+ "stop: 0 #bbf, stop: 1 #55f);" -+ "border: 1px solid #777;" -+ "height: 10px;" -+ "border-radius: 4px;" -+ "}" - -+ "QSlider::add-page:horizontal {" -+ "background: #fff;" -+ "border: 1px solid #777;" -+ "height: 10px;" -+ "border-radius: 4px;" -+ "}" - -+ "QSlider::handle:horizontal {" -+ "background: qlineargradient(x1:0, y1:0, x2:1, y2:1," -+ "stop:0 #eee, stop:1 #ccc);" -+ "border: 1px solid #777;" -+ "width: 13px;" -+ "margin-top: -2px;" -+ "margin-bottom: -2px;" -+ "border-radius: 4px;" -+ "}" - -+ "QSlider::handle:horizontal:hover {" -+ "background: qlineargradient(x1:0, y1:0, x2:1, y2:1," -+ "stop:0 #fff, stop:1 #ddd);" -+ "border: 1px solid #444;" -+ "border-radius: 4px;" -+ "}" - -+ "QSlider::sub-page:horizontal:disabled {" -+ "background: #bbb;" -+ "border-color: #999;" -+ "}" - -+ "QSlider::add-page:horizontal:disabled {" -+ "background: #eee;" -+ "border-color: #999;" -+ "}" - -+ "QSlider::handle:horizontal:disabled {" -+ "background: #eee;" -+ "border: 1px solid #aaa;" -+ "border-radius: 4px;" -+ "}"; + + "QSlider::groove:horizontal {" + + "border: 1px solid #bbb;" + + "background: white;" + + "height: 10px;" + + "border-radius: 4px;" + + "}" + + + "QSlider::sub-page:horizontal {" + + "background: qlineargradient(x1: 0, y1: 0, x2: 0, y2: 1," + + "stop: 0 #66e, stop: 1 #bbf);" + + "background: qlineargradient(x1: 0, y1: 0.2, x2: 1, y2: 1," + + "stop: 0 #bbf, stop: 1 #55f);" + + "border: 1px solid #777;" + + "height: 10px;" + + "border-radius: 4px;" + + "}" + + + "QSlider::add-page:horizontal {" + + "background: #fff;" + + "border: 1px solid #777;" + + "height: 10px;" + + "border-radius: 4px;" + + "}" + + + "QSlider::handle:horizontal {" + + "background: qlineargradient(x1:0, y1:0, x2:1, y2:1," + + "stop:0 #eee, stop:1 #ccc);" + + "border: 1px solid #777;" + + "width: 13px;" + + "margin-top: -2px;" + + "margin-bottom: -2px;" + + "border-radius: 4px;" + + "}" + + + "QSlider::handle:horizontal:hover {" + + "background: qlineargradient(x1:0, y1:0, x2:1, y2:1," + + "stop:0 #fff, stop:1 #ddd);" + + "border: 1px solid #444;" + + "border-radius: 4px;" + + "}" + + + "QSlider::sub-page:horizontal:disabled {" + + "background: #bbb;" + + "border-color: #999;" + + "}" + + + "QSlider::add-page:horizontal:disabled {" + + "background: #eee;" + + "border-color: #999;" + + "}" + + + "QSlider::handle:horizontal:disabled {" + + "background: #eee;" + + "border: 1px solid #aaa;" + + "border-radius: 4px;" + + "}"; #endif -- 2.18.0