How to replace all cursor appearances within a QML program? - qt

I'm working on a game that uses QML for its UI.
I would like to replace all cursors appearances with cursor-images that are more fitting to the game style (e.g. pointing skeleton hand instead of the normal Qt::ArrowCursor).
Calling QGuiApplication::setOverrideCursor() seams not to be a practical solution as I can not "overwrite" each MouseArea to call may replaceCursor() magic-global-function. For example the change column with cursor within a TableView is currently impossible for me to manipulate.
To me the most practical solution would be to replace the appearance of all cursors but leaf Qt with the tasks to correctly choose the cursor style.
Thanks for any help!

You can still use QGuiApplication::setOverrideCursor() to decorate your mouse areas. It works like a stack, you can set and then restore cursors, so you begin with setting an initial cursor from main.cpp, and then you use an "overloaded" MouseArea which sets its cursor using setOverrideCursor() as well, instead of using the QML functionality.
For example:
onContainsMouseChanged: {
if (containsMouse) Sys.setOverrideCursor(yourCursortype)
else Sys.restoreOverrideCursor()
}
Of course, that means you will have to create an auxiliary object that will call those functions from C++, and expose it to QML so it can be called from there.

Related

how the QtObject element works in QML

I just want to know what this QtObject elements does, its seems that is reactive, because in the tutorial that I followed, use it for update the color of a button, so, I want to know how I can use it, and how its works, and how I can use in other cases.
while your are working on QML file need to hide some properties from upper layer Item ( some thing's like private variable and methods).
best case for get a right way for incapsulation in QML is to using a internal item like QtObject .
in your code used a QtObject for block the external direct access to button color and bind the color to the button item state.
I assume you've read the docs? A QtObject is just the most basic type of of QML object. It doesn't do anything by itself. It's not visual. So it's just used for holding other properties.
In the example you provided, it's being used as a way to make pseudo-private variables. QML has no such thing as private variables, but if you put properties inside of an object, then they are not accessible to anything outside of this file (unless explicitly exposed). That's all it's being used for in your example. If you took the property dynamicColor and moved it outside of the QtObject, the code would still work exactly the same way. The only difference would be other QML files would be able to access (and therefore modify) dynamicColor.

Render a QQuickItem on a second window without changing its parent hierarchy

I have to render a QQuickItem owned by a particular window, into another. Basically MyQQuickItem owned by window1 to be rendered on window2. This switch has to happen in my app repeatedly due to a certain functionality.
I do the following to achieve the goal & the code basically works fine.
Code:
MyQQuickItem * myQuickItem = qmlEngine->rootObjects()[0]->findChild<QQuickItem*>("myquickitemobject");
myQuickItem->setParentItem(window1->contentItem());
// do the required on window2
// then set window1 as parent back again
myQuickItem->setParentItem(window2->contentItem());
Problem:
Above technique functionally works fine. But this requires me to flip flop a few times juggling between setting parent item from window1 to window2 & back again.
Question:
Is there some other way to share MyQQuickItem between the 2 windows? Or is it possible display MyQQuickItem on the both the windows alternatively without having to change the parent hierarchy?
You might use grabToImage() and display the grabbed image on your second window.
This might not be ideal, performance wise. You can find some questions on how to do this on this site. Especially interesting might be this.
I don't know your case, but it might be better, to have two instances of the same component displaying the same data model - possible with input for one disabled.

How to enable both internal reordering and external dropping in a Qt widget?

I have created a widget which inherits QListWidget.
My goal is for it to accept files dropped into it from an external file manager, and for the user to be able to reorder the elements in the widget. I can achieve both, but not at the same time.
If I just set
myWidget->setDragDropMode(QListView::InternalMove);
myWidget->setDragEnabled(true);
I can reorder the items within the widget, but I can't drop external items into it.
If I reimplement the dragMoveEvent, dragEnterEvent and dropEvent events, all of them just having acceptProposedAction(); and some debug messages inside them, I can drop external files into my widget, but I can no longer rearrange the items.
Is there a way to have the above two at the same time, or do I have to manage the items myself in the reimplemented functions? If so, how can I know if a dropped item is internal or external, and how can I know from which position it was taken and into which position in the list it was dropped into?
If I parse the mimeData which I got from the event, I can see whether it as a file or a text, and I get "qabstractitemmodeldatalist" if it was an internal item, but it still doesn't give me its position.
I can check event->pos() to know in pixels where the drop has been made, and event->source() to learn about what was dropped there, but is this really best practice, to start calculating pixel values and adding objects "manually"?
The solution was very simple: I just had to call the functions of the parent class at the end of each function I've overridden.
void myWidget::dropEvent(QDropEvent *event)
{
do_stuff_with_received_data(event);
QListWidget::dropEvent(event);
}

Qt set custom drag cursor?

How can I set the cursor used in Qt while performing a drag operation? I am using the QDrag class. The function setCursor takes a pixmap and has no way to specify the hotspot, nor do the docs specify that it could override the "no action" cursor.
I'm happy if I can just do an explicit cursor in mouseMoveEvent but I'm not sure how during a drag operation.
Checking the source code it appears Qt is lame in this regards and has no mechanism to do this. For the X11 code the function QDragManager::updateCursor variables which contain the cursors it uses. Those are created using the QCursor constructor with constant hot-spot values (0,0). The ForbiddenCursor is completely hard-coded, thus preventing any alternation.
To set the cursor it calls QApplication::changeOverrideCursor. As a static function there is no way to intercept that call.
Even if the pixmaps are set (via setCursor) the intial drag cursor is still the default. This just appears to be a defect in QT. This is at qdnd_x11.cpp:1948, the pointer cursor is forcibly set at the start of a drag
Thus there is no actual way to use custom cursors for the standard drag-n-drop.

QT drag and drop - Creating a temporary QLabel using qobject_cast

I'm trying to give a custom class that inherits from QLabel to be draggable. Towards that end, I'm trying to create a temporary copy of the class at the current mouse position using the following code inside of the class' mousePressEvent:
QLabel *child = qobject_cast{QLabel*}(this->childAt(event->pos()));
NOTE: this line has carrots instead of brackets, but stack overflow interprets it and takes it out
if (!child)
return;
The child is never created, and I can't figure out why. Any ideas?
If your code is within your QLabel-derived class, childAt() is not the right function. That would return a child widget contained within your label. It doesn't sound like that is what you are trying to do, but correct me if I am misunderstanding.
The object you want to copy is this, but "copy" can have many meanings in c++, and I am not sure exactly you are trying to do. You will probably have to implement it yourself, perhaps with a method called clone() that creates a new instance of your class and populates the values you need to reproduce.
I suspect, though, that there is a better way to implement the drag and drop functionality you are looking for without a copy.

Resources