Hi everyone,
Where can I get a library, or application, where a user can click on the screen some points, and then write to a file the points that the user picked. I would like to integrate this in an application I'm building.?
Printable View
Hi everyone,
Where can I get a library, or application, where a user can click on the screen some points, and then write to a file the points that the user picked. I would like to integrate this in an application I'm building.?
I suggest you implement your own widget for that. It's about 20 minutes of work.
For someone that knows what they're doing ;)Quote:
It's about 20 minutes of work.
Anyway, any good tutorials on that, or what QWidget could I use as a basis for this plotting widget?
No, really it is 20 minutes of work :)
QWidget is the obvious candidate for the base class. You might also search the forum, I remember implementing something like that as an example snippet, but it was few months ago, so it might not be easy to find it.
Basically you need to subclass QWidget and reimplement its paintEvent() for drawing and mouseReleaseEvent() for clicking. In the mouse event store coordinates of points you click on in some list (QVector<QPoint> is probably a good candidate) and schedule an update of the widget where you will repaint all the points. As for saving the result to a file, use QFile and optionally QDataStream or QTextStream.
Here is a rough implementation of the widget (not tested):
Code:
Q_OBJECT Q_PROPERTY(int count READ count) Q_PROPERTY(QVector<QPoint> points READ points WRITE setPoints) public: const QVector<QPoint> &points() { return m_points; } // for saving void setPoints(const QVector<QPoint> &pts) { m_points = pts; update(); } // for loading int count() const { return m_points.count(); } public slots: void clear() { m_points.clear(); update(); } protected: painter->drawPoints(m_points.constData(), m_points.size()); } void mouseReleaseEvent(QMouseReleaseEvent *me){ m_points << me->pos(); update(); } private: QVector<QPoint> m_points; };
There... 7 minutes :) 13 more to serialize and deserialize the points to a file ;)
No, really it is 20 minutes of work :)
QWidget is the obvious candidate for the base class. You might also search the forum, I remember implementing something like that as an example snippet, but it was few months ago, so it might not be easy to find it.
Basically you need to subclass QWidget and reimplement its paintEvent() for drawing and mouseReleaseEvent() for clicking. In the mouse event store coordinates of points you click on in some list (QVector<QPoint> is probably a good candidate) and schedule an update of the widget where you will repaint all the points. As for saving the result to a file, use QFile and optionally QDataStream or QTextStream.
Here is a rough implementation of the widget (not tested):
Code:
Q_OBJECT Q_PROPERTY(int count READ count) Q_PROPERTY(QVector<QPoint> points READ points WRITE setPoints) public: const QVector<QPoint> &points() { return m_points; } // for saving void setPoints(const QVector<QPoint> &pts) { m_points = pts; update(); } // for loading int count() const { return m_points.count(); } public slots: void clear() { m_points.clear(); update(); } protected: painter->drawPoints(m_points.constData(), m_points.size()); } void mouseReleaseEvent(QMouseReleaseEvent *me){ m_points << me->pos(); update(); } private: QVector<QPoint> m_points; };
There... 7 minutes :) 13 more left to serialize and deserialize the points to a file ;)
Hmmm I don't get it. I have this 2 files:
widget.h
Code:
#include <QtGui> #include <QVector> #include <QPoint> #include <QPainter> #include <QPaintDevice> #include <QEvent> #include <QCursor> Q_OBJECT Q_PROPERTY(int count READ count) Q_PROPERTY(QVector<QPoint> points READ points WRITE setPoints) public: const QVector<QPoint> &points() { return m_points;} // for saving void setPoints(const QVector<QPoint> &pts) { m_points = pts; update();} // for loading int count() const { return m_points.count();} public slots: void clear() { m_points.clear(); update();} protected: painter.drawPoints(m_points.constData(), m_points.size()); } update(); } } private: QVector<QPoint> m_points; };
and
main.cpp
Code:
#include <QApplication> #include <QHBoxLayout> #include "widget.h" int main(int argc, char *argv[]) { window->setWindowTitle("Blah"); Widget *wid = new Widget(); layout->addWidget(wid); window->show(); return app.exec(); }
It's not painting though :\
Compare my mouseReleaseEvent and yours. Mine is incorrect but is closer to being correct than yours ;)
Aghh I don't get it :\
I mean, don't I need an if stmt to verify what type of event it was.
I tried this:
Code:
update(); } }
I mean this is how Interpreting this: Maybe I've got something wrong.
1. You click.
2. mouseReleaseEvent() is called, it checks what type of MouseEvent it was if it is a release then it goes in.
3. point is added to the list of points.
4. update() is called which in turn calls paintEvent( )... I'm guessing.
Yet it still doesn't paint.. so there must be a flaw in my logic :(
btw the code I showed above is all I have, I shouldn't need more code to paint points on the widget, do I? O_o.
My implementation is correct and sufficient. It's just it should say QMouseEvent and not QMouseReleaseEvent in the signature.
In mouseReleaseEvent you can't get other event than a mouse release, that's why it's called "mouseReleaseEvent" and not "someGenericMouseEvent", there is no point in checking the event type. QCursor::pos() returns a global cursor position (relative to the origin of the screen) whereas QMouseEvent::pos() returns a local position (relative to the widget origin) and as you want to paint on the widget, you need coordinates relative to the widget and not the screen.