I've got an application which handles zooming in/out using the mouse wheel with this event in Qt Creator.
cpp
void QNodeView::wheelEvent(QWheelEvent* event) {
setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
// Scale the view / do the zoom
double scaleFactor = 1.15;
if(event->delta() > 0) {
// Zoom in
scale(scaleFactor, scaleFactor);
} else {
// Zooming out
scale(1.0 / scaleFactor, 1.0 / scaleFactor);
}
}
This is in the header file
h
protected:
//Take over the interaction
virtual void wheelEvent(QWheelEvent* event);
How can I add the ability to pan with the middle mouse button being pressed the user dragging the cursor?
I can post the project code if necessary just ask.
Thanks
Project files link (Qt Creator project)
https://www.dropbox.com/s/gbt4qqtdedltxek/QNodesEditor-master_01.zip?dl=0
At first, introduce some new member variables into your viewer class:
class QNodeView : public QGraphicsView
{
// ...
private:
int m_originalX = 0;
int m_originalY = 0;
bool m_moving = false;
};
Then reimplement mousePressEvent(), mouseMoveEvent(), and mouseReleaseEvent().
void QNodeView::mousePressEvent(QMouseEvent* event)
{
if (event->button() == Qt::MiddleButton)
{
// store original position
m_originalX = event->x();
m_originalY = event->y();
// set the "moving" state
m_moving = true;
}
}
void QNodeView::mouseMoveEvent(QMouseEvent* event)
{
if (m_moving)
{
// panning operates in the scene coordinates using x,y
QPointF oldp = mapToScene(m_originalX, m_originalY);
QPointF newp = mapToScene(event->pos());
QPointF translation = newp - oldp;
translate(translation.x(), translation.y());
m_originalX = event->x();
m_originalY = event->y();
}
}
void QNodeView::mouseReleaseEvent(QMouseEvent* event)
{
if (event->button() == Qt::MiddleButton)
{
m_moving = false;
}
}
Related
I have QVector<QPoint> m_vertices; in my drawingwidget.h
class DrawingWidget: public QWidget {
Q_OBJECT
public:
DrawingWidget(MainWindow *parent = 0);
~DrawingWidget();
QVector<QPoint> m_vertices;
I trying to implement adding/deleting vertices on my mainwindow. I managed to make the add function, now it's should be easy to delete them, but i am a bit confused.
The main idea is, that i have a pop-up menu, where i can choose a "tool". I can add vertex, remove vertex, move vertex, add line, delete line. The idea is , when i choose for example "Add Vertex" then the "m_state" will change to "ADD_VERTEX_SELECTED" so i can only add vertices and nothing else.
enum DrawingWidgetState {
NO_TOOL_SELECTED,
ADD_VERTEX_SELECTED,
MOVE_VERTEX_SELECTED,
DELETE_VERTEX_SELECTED,
ADD_LINE_SELECTED,
DELETE_LINE_SELECTED
};
Drawing
void DrawingWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.fillRect(event->rect(), Qt::blue);
painter.setBrush(Qt::black);
for(int i = 0; i < m_vertices.size() ; i++) {
painter.drawEllipse(m_vertices[i], 20, 20);
}
MousePress event. On left click, I have to delete the vertex that I clicked on
void DrawingWidget::mousePressEvent(QMouseEvent *event) {
if(m_state == ADD_VERTEX_SELECTED) {
if(event->button() == Qt::LeftButton) {
//m_x = event->x();
//m_y = event->y();
//update();
QPoint point = event->pos();
m_vertices.append(point);
update();
}
}
if(m_state == DELETE_VERTEX_SELECTED) {
if(event->button() == Qt::LeftButton) {
m_vertices.clear();
}
}
}
How can i do that ?
This code uses std::find_if together with a lambda expression to find the closest point. You probably want to allow a bit more leeway than the exact circle radius, but that is up to you.
auto it = std::find_if(m_vertices.begin(), m_vertices.end(), [point = event->pos](QPoint v) {
auto d = v - point;
return QPoint::dotProduct(d, d) < 400; // dotProduct returns square of distance
});
if (it != m_vertices.end()) {
m_vertices.erase(it);
}
Colleagues warned me that I was wrong to ask. That's why I completely redrafted my pervious question.
a) where best to create a new line
b) how to reliably select a specific line between 20 others
c) how best to move starting point of a line
d) how best to move end point of a line
e) how best to move line
f) how to delete a line
Everything is described in the documentation and examples, but each example chooses a different place for the actions. Someone uses the view, some scene and the other does most of the things in line. Someone uses bouding rect, another not, someone uses editing mode in view another not etc...
myscene.cpp
#include "myscene.h"
#include "myview.h"
#include "mymovingpoint.h"
#include <qgraphicsitem.h>
#include <qgraphicsview.h>
#include <qobject.h>
#include <qgraphicsview.h>
#include <qpoint.h>
#include <qmath.h>
/*
*
*
*/
myScene::myScene(QObject *parent)
: QGraphicsScene(parent)
{
myMode = myMode::InsertItem;
}
/*
*
*
*/
void myScene::mouseDoubleClickEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
# remove item added by clickevent, if doubleclicked
if(line)
{
removeItem(line);
}
# if doubleclick and left button, select existing item
if(mouseEvent->buttons().testFlag(Qt::LeftButton))
{
//QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
# itemAt() returns only the object exactly under the mouse
# function getNearObject return object 3 points around
QGraphicsItem *item = getNearObject(mouseEvent);
if(item)
{
myMode = myMode::EditItem;
myLineItem *tempLine = dynamic_cast<myLineItem*>(item);
oldLine = line;
line = tempLine;
QColor myclr;
myclr.setRgb(255,0,0,255);
line->setPen(QPen(myclr, 2));
line->addMovingPoints();
}
else
{
myMode = myMode::InsertItem;
}
}
}
/*
*
*
*/
#return nearest objects
QGraphicsItem* myScene::getNearObject(QGraphicsSceneMouseEvent *mouseEvent)
{
int roundvalue = -3;
int roundx;
int roundy;
QPointF pointf = mouseEvent->scenePos();
QPointF pointtmp;
roundx = roundvalue;
roundy = roundvalue;
while(roundy <= roundvalue*-1)
{
while(roundx <= roundvalue*-1)
{
pointtmp.setX(pointf.x()-roundx);
pointtmp.setY(pointf.y()-roundy);
QGraphicsItem *item = itemAt(pointtmp, QTransform());
if(item)
{
return item;
}
roundx += 1;
}
roundx += roundvalue;
roundy += 1;
}
return NULL;
}
/*
*
*
*/
void myScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if(mouseEvent->buttons().testFlag(Qt::LeftButton))
{
QGraphicsItem *item = itemAt(mouseEvent->scenePos(), QTransform());
if(myMode == myMode::InsertItem)
{
if(oldLine)
{
myLineColor.setRgb(213, 182, 10, 255);
oldLine->setPen(QPen(myLineColor, 2));
}
}
if(myMode == myMode::EditItem)
{
myLineItem *tempLine = dynamic_cast<myLineItem*>(item);
if(tempLine)
{
oldLine = line;
line = tempLine;
QColor myclr;
myclr.setRgb(255,0,0,255);
line->setPen(QPen(myclr, 2));
myMovingPoint myPoint(line);
}
}
else if(myMode == myMode::InsertItem)
{
oldLine = line;
if(mouseEvent->modifiers() & Qt::ControlModifier)
{
line = new myLineItem(QLineF(toNearest5(mouseEvent->scenePos()), toNearest5(mouseEvent->scenePos())));
}
else
{
line = new myLineItem(QLineF(mouseEvent->scenePos(), mouseEvent->scenePos()));
}
myLineColor.setRgb(213, 182, 10, 255);
line->setPen(QPen(myLineColor, 2));
}
else
{
QGraphicsScene::mousePressEvent(mouseEvent);
}
}
}
/*
*
*
*/
void myScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
if(!items().contains(line))
{
addItem(line);
}
if(mouseEvent->buttons().testFlag(Qt::LeftButton))
{
QLineF newLine;
if(myMode == myMode::InsertItem)
{
if(mouseEvent->modifiers() & Qt::ControlModifier)
{
newLine = QLineF(toNearest5(line->line().p1()), toNearest5(mouseEvent->scenePos()));
}
else
{
newLine = QLineF(line->line().p1(), mouseEvent->scenePos());
}
myLineColor.setRgb(213, 182, 10, 255);
line->setLine(newLine);
update();
}
else if(myMode == myMode::EditItem)
{
QLineF newLine = QLineF(line->line().p1(), mouseEvent->scenePos());
line->setLine(newLine);
update();
}
}
QGraphicsScene::mouseMoveEvent(mouseEvent);
}
/*
*
*
*/
void myScene::mouseReleaseEvent(QGraphicsSceneMouseEvent *mouseEvent)
{
myMode = myMode::InsertItem;
QGraphicsScene::mouseReleaseEvent(mouseEvent);
}
/*
*
*
*/
void myScene::keyPressEvent(QKeyEvent * keyEvent)
{
if(keyEvent->key() == Qt::Key_Delete)
{
if(line)
{
removeItem(line);
}
}
}
/*
*
*
*/
QPointF myScene::toNearest5(QPointF i)
{
int shift = 10;
int r = i.x();
int s = i.y();
r = (i.x()+5.0)/10;
s = (i.y()+5.0)/10;
r = r*10;
s = s*10;
QPointF output = QPointF(r, s);
return (output);
}
mysceneview.cpp
#include "myview.h"
#include <qmath.h>
#include <qmatrix.h>
myView::myView(QGraphicsScene *scene, QWidget *parent)
: QGraphicsView(scene, parent)
{
}
void myView::keyPressEvent(QKeyEvent *event)
{
QGraphicsView::keyPressEvent(event);
}
void myView::keyReleaseEvent(QKeyEvent *event)
{
QGraphicsView::keyReleaseEvent(event);
}
void myView::enterEvent(QEvent *event)
{
viewport()->setCursor(Qt::ArrowCursor);
QGraphicsView::enterEvent(event);
}
void myView::mousePressEvent(QMouseEvent* event)
{
if (event->modifiers() & Qt::ControlModifier)
{
viewport()->setCursor(Qt::ArrowCursor);
_lastPos = QPoint(event->pos());
//_lastPos = QPoint(event->pos().x()-event->pos().x()%5, event->pos().y()-event->pos().y()%5);
}
else
{
viewport()->setCursor(Qt::ArrowCursor);
_lastPos = event->pos();
}
QGraphicsView::mousePressEvent(event);
}
void myView::mouseMoveEvent(QMouseEvent* event)
{
viewport()->setCursor(Qt::ArrowCursor);
if (event->buttons().testFlag(Qt::RightButton))
{
QScrollBar *hBar = horizontalScrollBar();
QScrollBar *vBar = verticalScrollBar();
QPoint delta = event->pos() - _lastPos;
_lastPos = event->pos();
hBar->setValue(hBar->value() + (isRightToLeft() ? delta.x() : -delta.x()));
vBar->setValue(vBar->value() - delta.y());
//event->ignore();
}
QGraphicsView::mouseMoveEvent(event);
}
void myView::mouseReleaseEvent(QMouseEvent* event)
{
viewport()->setCursor(Qt::ArrowCursor);
QGraphicsView::mouseReleaseEvent(event);
}
#if QT_CONFIG(wheelevent)
void myView::wheelEvent(QWheelEvent *e)
{
if (e->delta() > 0)
{
x=x+0.1;
qreal scale = x;
QMatrix matrix;
matrix.scale(scale, scale);
setMatrix(matrix);
//zoomIn(6);
}
else
{
x=x-0.1;
qreal scale = x;
QMatrix matrix;
matrix.scale(scale, scale);
setMatrix(matrix);
//zoomOut(6);
}
e->accept();
}
#endif
you should define in your model, what's a scene, what's a view, and what is and an item.
logically this is how it goes:
scene: collection of drawable objects, cannot be viewed.
view: a window on the scene, if the object belonging to the scene is in this window, it is shown, if it is not then it's occluded
item: is a draw-able object, stores the position of its vertex in object coordinate.
when you draw you draw in the view, then the object stores the points in its object space coordinate, they will be constant during zooms, moves, rotations and pans, they change only when you select the vertex and move it in the view.
so mylineitem is only a container for an absolute coordinate.
scene is a container of all the mylineitem, just a list of objects
view is your controller of the way the system draws the items of the scene.
this model allows you to export your drawable items either individually or as a scene without worrying about remaping the points to the new coordinate space of the new view.
Do all your object editing in the view, because it defines the distance between the points in its coordinate system.
expl:
view, coordinate system: Cartesian, 10x10x10 cm
your draw a line p1-p2
p1(0,0,0) origin of the object space, p2(1,1,1) and it maps in the view to p1view(3,5,4) expl and p2view(13,15,14) in view coordinate. means each unit in object space is 10cm in view space.
export this line to another view where system: 20x20x20 cm then line keeps its relative size and changes its coordinate to preserve it.
in QGraphicview,
if we set it with : ui->graphicsView->setDragMode(QGraphicsView::ScrollHandDrag);
this code make graphicsview can scroll items with mouse pressed and drag.
How can we make QListView or QTableView as the QGraphicsView?
You will need to subclass these widgets and reimplement QWidget::mousePressEvent, QWidget::mousMoveEvent and QWidget::mouseReleaseEvent. However you will have to be careful because you may be interfering with actions that are mapped to these by default implementations (e.g. selecting) so it would need to be tweaked a bit. For example (assumed subclass of QListView):
void MyListView::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::RightButton) //lets map scrolling to right button
m_ScrollStart = event->pos(); //QPoint member, indicates the start of the scroll
else
QListView::mousePressEvent(event);
}
and then
void MyListView::mouseMoveEvent(QMouseEvent *event)
{
if(!m_ScrollStart.isNull()) //if the scroll was started
{
bool direction = (m_ScrollStart.y() < event->pos().y()); //determine direction, true is up (start is below current), false is down (start is above current)
int singleStep = (direction ? 10 : -10); //fill in the desired value
verticalScrollBar()->setValue(verticalScrollBar()->value() + singleStep);
//scroll by the certain amount in determined direction,
//you decide how much will be a single step... test and see what you like
}
QListView::mouseMoveEvent(event);
}
and finally
void MyListView::mouseReleaseEvent(QMouseEvent *event)
{
m_ScrollStart = QPoint(); //resets the scroll drag
QListView::mouseReleaseEvent(event);
}
like Resurrection did mention
You will need to subclass these widgets and reimplement QWidget::mousePressEvent, QWidget::mousMoveEvent and QWidget::mouseReleaseEvent
but below code is more preferred by us:
class MyListView : public QListView
{
typedef QListView super;
public:
explicit MyListView(QWidget *parent = 0);
protected:
// QWidget interface
void mousePressEvent(QMouseEvent *) Q_DECL_OVERRIDE;
void mouseReleaseEvent(QMouseEvent *) Q_DECL_OVERRIDE;
void mouseMoveEvent(QMouseEvent *) Q_DECL_OVERRIDE;
private:
enum DragState {
DragStopped,
DragStarted,
Dragged
};
quint8 m_dragState;
int m_dragStartPos;
};
MyListView::MyListView(QWidget *parent)
: super(parent)
, m_dragState(DragStopped)
, m_dragStartPos(-1)
{
}
void MyListView::mousePressEvent(QMouseEvent *event)
{
if(event->button() == Qt::LeftButton) {
m_dragState = DragStarted;
m_dragStartPos = event->pos().y();
} else
super::mousePressEvent(event);
}
void MyListView::mouseReleaseEvent(QMouseEvent *event)
{
if(m_dragState) {
m_dragState = DragStopped;
m_dragStartPos = -1;
return;
}
super::mouseReleaseEvent(event);
}
void MyListView::mouseMoveEvent(QMouseEvent *event)
{
if(m_dragState != DragStopped) {
const int itemSize = sizeHintForRow(0) / 2;
const int distance = qAbs(m_dragStartPos - event->pos().y());
if(distance > 10)
m_dragState = Dragged;
if(distance > itemSize) {
QScrollBar *scrollBar = this->verticalScrollBar();
int stepCount = (distance/itemSize);
if(m_dragStartPos < event->pos().y())
stepCount = -stepCount; //scrolling up
scrollBar->setValue(scrollBar->value() + (stepCount * scrollBar->singleStep()));
m_dragStartPos = event->y();
}
return;
}
super::mouseMoveEvent(event);
}
I am building a map widget (something like the google map) using Qt, basically I used a QGraphicsScene to display the map tile.
Now I want to add a scale ruler to the widget just like the one in google map.
Any suggestions about how could I realize this?
Take a look at this example:
Structure your code base as following:
Write a class inheriting descendants class of QAbstractScrollArea (As example QGraphicsView, QMdiArea, QPlainTextEdit, QScrollArea, QTextEdit, QColumnView, QHeaderView, QListView, QTableView, QTreeView etc.)
In the constructor of your class call setViewportMargins and set the margins of left/top/right/bottom areas length.
Create a QGridLayout and adds your custom Ruler/Scale in the layout.
Set this layout calling setLayout
Example:
setViewportMargins(RULER_BREADTH,RULER_BREADTH,0,0);
QGridLayout* gridLayout = new QGridLayout();
gridLayout->setSpacing(0);
gridLayout->setMargin(0);
mHorzRuler = new QDRuler(QDRuler::Horizontal);
mVertRuler = new QDRuler(QDRuler::Vertical);
QWidget* fake = new QWidget();
fake->setBackgroundRole(QPalette::Window);
fake->setFixedSize(RULER_BREADTH,RULER_BREADTH);
gridLayout->addWidget(fake,0,0);
gridLayout->addWidget(mHorzRuler,0,1);
gridLayout->addWidget(mVertRuler,1,0);
gridLayout->addWidget(this->viewport(),1,1);
this->setLayout(gridLayout);
QDRuler: The ruler class
#define RULER_BREADTH 20
class QDRuler : public QWidget
{
Q_OBJECT
Q_ENUMS(RulerType)
Q_PROPERTY(qreal origin READ origin WRITE setOrigin)
Q_PROPERTY(qreal rulerUnit READ rulerUnit WRITE setRulerUnit)
Q_PROPERTY(qreal rulerZoom READ rulerZoom WRITE setRulerZoom)
public:
enum RulerType { Horizontal, Vertical };
QDRuler(QDRuler::RulerType rulerType, QWidget* parent)
: QWidget(parent), mRulerType(rulerType), mOrigin(0.), mRulerUnit(1.),
mRulerZoom(1.), mMouseTracking(false), mDrawText(false)
{
setMouseTracking(true);
QFont txtFont("Goudy Old Style", 5,20);
txtFont.setStyleHint(QFont::TypeWriter,QFont::PreferOutline);
setFont(txtFont);
}
QSize minimumSizeHint() const
{
return QSize(RULER_BREADTH,RULER_BREADTH);
}
QDRuler::RulerType rulerType() const
{
return mRulerType;
}
qreal origin() const
{
return mOrigin;
}
qreal rulerUnit() const
{
return mRulerUnit;
}
qreal rulerZoom() const
{
return mRulerZoom;
}
public slots:
void setOrigin(const qreal origin)
{
if (mOrigin != origin)
{
mOrigin = origin;
update();
}
}
void setRulerUnit(const qreal rulerUnit)
{
if (mRulerUnit != rulerUnit)
{
mRulerUnit = rulerUnit;
update();
}
}
void setRulerZoom(const qreal rulerZoom)
{
if (mRulerZoom != rulerZoom)
{
mRulerZoom = rulerZoom;
update();
}
}
void setCursorPos(const QPoint cursorPos)
{
mCursorPos = this->mapFromGlobal(cursorPos);
mCursorPos += QPoint(RULER_BREADTH,RULER_BREADTH);
update();
}
void setMouseTrack(const bool track)
{
if (mMouseTracking != track)
{
mMouseTracking = track;
update();
}
}
protected:
void mouseMoveEvent(QMouseEvent* event)
{
mCursorPos = event->pos();
update();
QWidget::mouseMoveEvent(event);
}
void paintEvent(QPaintEvent* event)
{
QPainter painter(this);
painter.setRenderHints(QPainter::TextAntialiasing | QPainter::HighQualityAntialiasing);
QPen pen(Qt::black,0); // zero width pen is cosmetic pen
//pen.setCosmetic(true);
painter.setPen(pen);
// We want to work with floating point, so we are considering
// the rect as QRectF
QRectF rulerRect = this->rect();
// at first fill the rect
//painter.fillRect(rulerRect,QColor(220,200,180));
painter.fillRect(rulerRect,QColor(236,233,216));
// drawing a scale of 25
drawAScaleMeter(&painter,rulerRect,25,(Horizontal == mRulerType ? rulerRect.height()
: rulerRect.width())/2);
// drawing a scale of 50
drawAScaleMeter(&painter,rulerRect,50,(Horizontal == mRulerType ? rulerRect.height()
: rulerRect.width())/4);
// drawing a scale of 100
mDrawText = true;
drawAScaleMeter(&painter,rulerRect,100,0);
mDrawText = false;
// drawing the current mouse position indicator
painter.setOpacity(0.4);
drawMousePosTick(&painter);
painter.setOpacity(1.0);
// drawing no man's land between the ruler & view
QPointF starPt = Horizontal == mRulerType ? rulerRect.bottomLeft()
: rulerRect.topRight();
QPointF endPt = Horizontal == mRulerType ? rulerRect.bottomRight()
: rulerRect.bottomRight();
painter.setPen(QPen(Qt::black,2));
painter.drawLine(starPt,endPt);
}
private:
void drawAScaleMeter(QPainter* painter, QRectF rulerRect, qreal scaleMeter, qreal startPositoin)
{
// Flagging whether we are horizontal or vertical only to reduce
// to cheching many times
bool isHorzRuler = Horizontal == mRulerType;
scaleMeter = scaleMeter * mRulerUnit * mRulerZoom;
// Ruler rectangle starting mark
qreal rulerStartMark = isHorzRuler ? rulerRect.left() : rulerRect.top();
// Ruler rectangle ending mark
qreal rulerEndMark = isHorzRuler ? rulerRect.right() : rulerRect.bottom();
// Condition A # If origin point is between the start & end mard,
//we have to draw both from origin to left mark & origin to right mark.
// Condition B # If origin point is left of the start mark, we have to draw
// from origin to end mark.
// Condition C # If origin point is right of the end mark, we have to draw
// from origin to start mark.
if (mOrigin >= rulerStartMark && mOrigin <= rulerEndMark)
{
drawFromOriginTo(painter, rulerRect, mOrigin, rulerEndMark, 0, scaleMeter, startPositoin);
drawFromOriginTo(painter, rulerRect, mOrigin, rulerStartMark, 0, -scaleMeter, startPositoin);
}
else if (mOrigin < rulerStartMark)
{
int tickNo = int((rulerStartMark - mOrigin) / scaleMeter);
drawFromOriginTo(painter, rulerRect, mOrigin + scaleMeter * tickNo,
rulerEndMark, tickNo, scaleMeter, startPositoin);
}
else if (mOrigin > rulerEndMark)
{
int tickNo = int((mOrigin - rulerEndMark) / scaleMeter);
drawFromOriginTo(painter, rulerRect, mOrigin - scaleMeter * tickNo,
rulerStartMark, tickNo, -scaleMeter, startPositoin);
}
}
void drawFromOriginTo(QPainter* painter, QRectF rulerRect, qreal startMark, qreal endMark, int startTickNo, qreal step, qreal startPosition)
{
bool isHorzRuler = Horizontal == mRulerType;
int iterate = 0;
for (qreal current = startMark;
(step < 0 ? current >= endMark : current <= endMark); current += step)
{
qreal x1 = isHorzRuler ? current : rulerRect.left() + startPosition;
qreal y1 = isHorzRuler ? rulerRect.top() + startPosition : current;
qreal x2 = isHorzRuler ? current : rulerRect.right();
qreal y2 = isHorzRuler ? rulerRect.bottom() : current;
painter->drawLine(QLineF(x1,y1,x2,y2));
if (mDrawText)
{
QPainterPath txtPath;
txtPath.addText(x1 + 1,y1 + (isHorzRuler ? 7 : -2),this->font(),QString::number(qAbs(int(step) * startTickNo++)));
painter->drawPath(txtPath);
iterate++;
}
}
}
void drawMousePosTick(QPainter* painter)
{
if (mMouseTracking)
{
QPoint starPt = mCursorPos;
QPoint endPt;
if (Horizontal == mRulerType)
{
starPt.setY(this->rect().top());
endPt.setX(starPt.x());
endPt.setY(this->rect().bottom());
}
else
{
starPt.setX(this->rect().left());
endPt.setX(this->rect().right());
endPt.setY(starPt.y());
}
painter->drawLine(starPt,endPt);
}
}
private:
RulerType mRulerType;
qreal mOrigin;
qreal mRulerUnit;
qreal mRulerZoom;
QPoint mCursorPos;
bool mMouseTracking;
bool mDrawText;
};
I want to change the color of an ellipse when I move my mouse over it.
But I haven't found anything from reference and auto-complete from Qt Creator.
Do you guys know how to do it?
Some of my code:
void DrawingWidget::paintEvent(QPaintEvent *event) {
QPainter painter(this);
painter.fillRect(event->rect(), Qt::white);
for(int i = 0; i < pointList.size(); i++) {
if (pointList[i].x() >= 0 && pointList[i].y() >= 0)
painter.drawEllipse(pointList[i], 10, 10);
}
painter.drawLines(lineList);
m_mainWindow->updateCount();
}
Mouse press event handler:
void DrawingWidget::mousePressEvent(QMouseEvent *event) {
if (event->button() == Qt::LeftButton
&& event->buttons() == Qt::LeftButton) {
// DO STUFFF
}
}
Mouse move event handler:
void DrawingWidget::mouseMoveEvent(QMouseEvent *event) {
if (m_mainWindow->getSelectedTool() == MainWindow::moveVertexTool) {
m_x = event->x();
m_y = event->y();
if (isPointNear(m_x, m_y)) {
//STUFF
}
update();
}
}
}
Now I just need a mouse OVER event (handler).
I think what you are looking for are enter and leave events.
Use QWidget::underMouse() for check if the widget is under the mouse cursor.
For example:
void IconButton::paintEvent(QPaintEvent *)
{
QPainter painter(this);
// Note isDown should really use the active state but in most styles
// this has no proper feedback
QIcon::Mode mode = QIcon::Disabled;
if (isEnabled()) {
if (isDown())
mode = QIcon::Selected;
else
mode = underMouse() ? QIcon::Active : QIcon::Normal;
}
QPixmap pixmap = icon().pixmap(iconSize(), mode);
QRect pixmapRect = QRect(0, 0, pixmap.width(), pixmap.height());
pixmapRect.moveCenter(rect().center());
if (m_autoHide)
painter.setOpacity(m_iconOpacity);
painter.drawPixmap(pixmapRect, pixmap);
}
This value is not updated properly during drag and drop operations.