How to handle Stylus/Pen input in QML - qt

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.

Related

QT5 How to paint with two events?

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.

How to draw something in a tooltip?

I am trying to develop a functionality using Qt which I don't know whether it is possible to implement. Here is the requirement:
When the user hovers over a node (an object derived from QGraphicsItem), a window will be shown near the node, in the window there might be some histograms or buttons that can be clicked to show further information. When the mouse leaves the window, it will automatically close.
I tried to use a tooltip, because it can pop-up near the node and close when the mouse leaves it, but it can only show text. So, it still cannot work that way. I am wondering if there is another way to do this? I did lots of google search, but there is still no answer.
Thanks so much for helping me with this.
If you're ok with using a 3rd party library, Qxt provides a class that provides a tooltip that is QWidget based, which will let you use an arbitrary widget as the tooltip rather than just text.
See: Qxt::ToolTip
you don't have to use tooltip for your app
you can use or call widget or dialog, on hover mouse event
Please refer Qt Example EmbeddedDialog Example, It is advanced, But you can understand how hover Enter/Leaving events are working. I personally prefer don not create instance of Popupdialog for each item, create it if only nesessary. Otherwise create one dialog and pass its reference to all the items through the constructor initialization.
1. These are the API you are intrested on, reimplemet this.
QGraphicsItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event) and void QGraphicsItem::hoverLeaveEvent(QGraphicsSceneHoverEvent *event)
2. When You create Dialog, You can pass Qt::WindowFlags as Qt::ToolTip.

Qt : keyboard focus

I am writing a program in Qt that looks like this:
The main window is my class Window : QWidget, it has a QGridLayout containing four other widgets (Input_Menu : QWidget and Output_Menu : QWidget, and then two Canvas : QWidget)
I would like to trigger certain events when the user strikes a key. The problem is, the Window sometimes loses focus (it goes, say to Input_Menu, or maybe a button in Input_Menu...)
I have tried the following solutions, but they seem unsatisfactory (and dirty):
Give Window the focus whenever it loses it.
Tell each widget who could have the focus to trigger Window's KeyPressEvent function (or a clone of it) whenever it receives a keyboard event.
Ideally, I would like that if a widget receives an event (say a keyboard event) and doesn't know what to do with it, it should automatically call its parent's event handler. I would have hoped this to be a default feature of Qt but it doesn't look like it. On the other hand I am really confused about the whole focus thing, I don't really get what's going on. Can someone explain this to me: I have included a std::cout << "key pressed" << std::endl; in my Window::KeyPressEvent function. When I first run my program, it seems the focus is on the top QComboBox in Input_Menu: if I hit the Up/Down keys, I navigate in that box and no "key pressed" is showed in my console. If I hit most letters, nothing happens. But if I hit Left/Right keys, I do get a "key pressed" in my console!?
Thanks a lot in advance for your insights.
You can install an event filter on QApplication to filter the relevant QEvent::KeyPress events globally. From the Qt documentation:
It is also possible to filter all events for the entire application,
by installing an event filter on the QApplication or QCoreApplication
object. Such global event filters are called before the
object-specific filters. This is very powerful, but it also slows down
event delivery of every single event in the entire application; the
other techniques discussed should generally be used instead.
Besides the performance considerations, remember to check if your window currently has the focus before you filter the key event, or you might break popup dialogs or input into other windows.
Actually, I found that for keys that are modifiers (such as Shift, Control), Qt supports finding out whether they are pressed.
Eg : if(QApplication::keyboardModifiers() == Qt::ShiftModifier) ...
This is good enough.

Directing keyboard input to a widget when using Qt

I am creating a GUI using Qt. Basically it is an interactive map that shows robots moving in an arena in real time and allows the user to interact with the robots(tell them to go/stop) by using the mouse and keyboard keys. I used opengl to create the map itself and everything is working perfectly, I can see the robots moving on the map and I can press different keys on the keyboard and send the actual robots commands.
Now, I need to take this map and make it become a part of a bigger GUI that holds this map along with other objects as well,not all objects are necessarily using opengl. So, by using the Qt creator (designer) I have some dragged/dropped tabs in my GUI and I have also added a "dockwidget" in my GUI. The dockwidget holds in it the interactive map that I had created earlier. Now, however I can no longer send commands using my keyboard to my map. I can still click on different robots on my map and I can see that they get selected and change colors (as I coded it to do) but pressing keys have no corresponding actions(as it has been coded).
This is what the map by itself looks like. http://dl.dropbox.com/u/46437808/collision3.png
This is the map as a docked widget. (Inside the widge,I was able to click on one robot and make it turn yellow) https://www.dropbox.com/s/lpo43rl6z4268im/argHRI.png
So, my question is how do we direct keyboard input to a specific widget in a window when using Qt. From what I read that it might have to do with setting focus policy. So, I tried to set the focuspolicy of my dockwidget to "StrongFocus" (so that it can take keyboard input) in the constructor but that did not help.
Here is the code in which I'm setting my map as the dockwidget and I'm trying to set the focus as well.
#include "ui_arghri.h"
argHRI::argHRI(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::argHRI)
{
ui->setupUi(this);
ui->dockMap->activateWindow();
//ui->dockMap->keyboardGrabber();
//ui->dockMap->grabKeyboard();
ui->dockMap->setFocus();
ui->dockMap->setFocusPolicy(Qt::StrongFocus);
}
argHRI::~argHRI()
{
delete ui;
}
void argHRI::addMap(Map * map)
{
qDebug()<<"argHRI::in AddMap test is "<<map->test;
//ui->dockMap->show();
ui->dockMap->setWidget(map);
}
Add an event filter that handles KeyPress events to your class. There are examples here: http://doc.qt.io/archives/qt-4.7/eventsandfilters.html
Just don't forget to add:
installEventFilter(this);
to the constructor or it won't work otherwise.

Attach Qt windows?

Is there any way to attach two Qt windows together? For example, if window A is the main window and window B is another widget I want to be able to show window B to the side of A and have both windows move together if the windows are dragged.
Not that I am aware of, but you can try following the trail of QMoveEvent. When a given widget is moved void QWidget::moveEvent ( QMoveEvent * event ) is called, and the QMoveEvent contains both old and new pos. Using this information, you can inject a move event in the other widget as well, and make it follow.
Of course, I am speaking of two independent widgets, each one in its own window. If they are contained, you don't need anything but a Layout management (see QLayout and related classes).
I don't work with Qt since a long time, so there could be a better method, but if I had to do it right now, this is the strategy I would use.
Also, I have the feeling that the QMoveEvent will be invoked only at start and end, unless you enable mouse tracking. If the former is the case, you will obtain that the other widget will "teleport" at the end of the move, instead of following smoothly.
You might be after something like this:
http://doc.qt.io/archives/4.6/qt4-mainwindow.html
Window A would be a QMainWindow and window B would be a QDockWidget.

Resources