I have a area shows waveform of a wave file.
I want that a line follow mouse moving like audio editor and this line's behavior is like progressbar when it is playing.
But there's only one paintEvent function, it works well when it is not playing, how to implement it?
Remember that the paintEvent isn't meant to react to user interaction directly. You should handle interaction in relevant mouse/keyboard event handlers, and modify a data structure that describes what's to be shown. Before returning from the event handler, queue an update using QWidget::update().
The paintEvent will be then called from the event loop, and should repaint the widget based on the updated data. Also don't forget that the paintEvent can be called at any time, and that you can paint on the widget only from within the paintEvent.
Related
I am creating a simple drawing application and would like my app handle pen (stylus like Apple Pencil) input. The app is written in Qml/Qt Quick. I know that when using QWidgets you can handle tablet events using QTabletEvent (example), but how I can handle pen input in QML (using MouseArea does not work and I had no luck with PointHandler either). Does anyone know if it is possible to handle Pen input in Qt Quick?
Try using QML TapHandler: https://doc.qt.io/qt-5/qml-qtquick-taphandler.html
acceptedDevices: PointerDevice.Mouse | PointerDevice.Stylus
Looking at the example linked by #Albertino80 , I subclassed QQuickWindow which inherits QWindow and hence is able to receive tablet events (void tabletEvent(QTabletEvent* event). These events can then be used to emit appropriate signals that can be propapated to other QObjects. This method works ok, but it has the problem that event coordinates are not local to the item where they are consumed, instead one has to manually recalculate the position of each event by mapping the coordinates to the custom window.
By default QSlider reacts on mouse wheel only when cursor is on it. I want to control slider by mouse wheel not matter where the cursor is (of course only when my application has focus).
What's the best way to achieve that?
I just learned that mouse doesn't generate signals. So looks like I need to override wheelEvent in main window and use raise or lower method in it. But I guess that can cause double increment (or decrement) of slider value when mouse is hovering it.
So once again: What's the best way to achieve what I described?
You can override the wheelEvent() in your MainWindow and redirect it to your slider control, that is indeed one option.
Another option is to install an event filter on the qApp instance. This even filter then can check whether the event type is QEvent::Wheel, and when the receiver is not the slider, then again redirect it to the slider. Should work just as well.
Question/Issue
I tried reimplementing the event method in a custom delegate to handle clicks. The delegate is used to render table cells in a table view. However, I do not get any events for the delegate (the method is never called according to the debuger). Is there anything special I need to do so my delegate can track events (in particular mouse entering/exiting, clicks)?
Context
I would like to create my own data representation for table cells. The functionality should be close to a button, but slightly different. I read that the two options for implementing buttons in table are either setting a cell widget which supposedly has a high performance cost (I did not quite understand why) or using a delegate.
Since I want different behaviour than that of a button, and for the speed myth I decided to go with a delegate.
Mouse events are send to the QAbstractItemDelegate::editorEvent() method, even if they don't start editing of the item.
See: http://doc.qt.io/qt-5/qabstractitemdelegate.html#editorEvent
I am using a QAbstractScrollArea + a custom QWidget derivative widget as "the" widget
(having sizeHint() overriden).
The application needs to constantly update the QWidget content during mouseMove (kind of
a drag, but not exactly, it is a drawing tool to draw lines between objects, thus the mouse
cursor needs to change + the line needs to be drawn on the fly).
The application works fine, e.g. I can render the content properly, scrollbars visible,
I can manual update the viewport during scrollContentsBy, etc.
However regardless that I manually fire a update() (or repaint()) call in mouseMoveEvent,
the paintEvent will only be called after the "drag" process is over, e.g. the mouseReleaseEvent is fired.
And I'm clueless why this happens. Obviously if I do the update directly within the
mouseMoveEvent, it'll be rejected by QPainter (as I can't instantiate a QPainter within
the mouseMoveEvent - Qt drops "paintEngine should no longer be called" when trying to do that).
Any suggestion is welcomed :)
Thanks,
Meh, lame me. Never never mix "update()" with "viewport()->update()"
I have a problem:
I'm creating a widget which displays current date's day number. It's like a button, but it's not derived from QPushButton class. Just from QWidget. So I've reimplemented enterEvent(), leaveEvent(), mousePressEvent(), mouseReleaseEvent(). I do call update() inside these methods and widget has realistic button behavior (paintEvent() is reimplemented also).
But when I change system date and hover that widget with other window, my widget doesn't get paintEvent() and the old date is displayed. Only when I place mouse over it, widget repaints it's contents.
I guess there is a feature (like buffering) which paints old contents on hovering with other window to avoid unnecessary recalculations. But I need to disable it. Tried to set many attributes (the Qt::WidgetAttribute enum). But it doesn't work.
I think you should find a way to detect that the system time has changed and call update() when that happens. Any other method (like detecting the "hovering" of a window or waiting for a mouse event) will cause the update to occur too late.