make the cursor on the screen invisible after it has stopped - qt

first, sorry for my poor english !
I want to make the cursor on the screen become invisible after it has stopped moving for 10s. I think this problem can be solved easily if there is a signal like positionChanged(QPoint lastPos , QPoint currentPos) existed,lastPos means the last position of the cursor (hot spot) of the primary screen in global screen coordinates, currentPos means the current position, this signal should be emitted once the cursor stopped moving .Note the Mouse move events here should occur even when a mouse button is not pressed down, i.e. there is mouse tracking with cursor.In Qt, mouse tracking could be enabled with QWidget::setMouseTracking(), however my problem is not restricted to Qt, it is system wide, I want to do this on Windows now ,anyone knows how to enable mouse tracking here ?
any other solution is also welcome !

You can use an event filter to see if a mouse moved:
bool MainWindow::eventFilter(QObject *obj, QEvent *event)
{
if (event->type() == QEvent::MouseMove)
{
QMouseEvent *mouseEvent = static_cast<QMouseEvent*>(event);
qDebug() << (QString("Moved! (%1,%2)").arg(mouseEvent->pos().x()).arg(mouseEvent->pos().y()));
}
return false;
}
and install it in your MainWindow or so:
qApp->installEventFilter(this);
Then, make a 10 second timer which gets reset when the mouse moves (and makes the cursor visible again). To make the mouse cursor vanish, you can call this when your timer runs out:
QApplication::setOverrideCursor(Qt::BlankCursor);
To make the cursor visible again, call:
QApplication::restoreOverrideCursor()

Related

Restore window to normal doesn't work after maximized in qt on ubuntu 18.04

I meet two problems, I searched, but they seems not so easy as I think.
I'm working on ubuntu-18.04 with qt-5.15.x. And my two problems are:
cannot restore my window after maximizing it.
cannot move my window out of my screen with mouse dragging
Can not restore
Firstly, I set my window frameless, and then using a button standing for maximize or restoreoperations to trigger maximization or normal
// set fremeless in contruction
setWindowFlags(Qt::FramelessWindowHint | windowFlags());
// maximaization slot or restore
void WindowTitle::onButtonMaxClicked()
{
QWidget *pWin = window();
if(pWin->isMaximized())
{
pWin->showNormal();
}
else
{
pWin->showMaximized();
}
}
What I expected is when I click button ,window will maximized, and that is true indeed. Then clicking on button again, window will return original position and size again, but that doesn't happen, instead, window's height is correct, but its width is equal screen(getting rid of applications docker bar), x-axis value is wrong too. And I have tried setGeometry after I have stored its value, but failed.
Can not move outside
I can make sure that I have set correct position with
void WindowTitle::mouseMoveEvent(QMouseEvent *event)
{
if (m_isPressed)
{
QPoint movePoint = event->globalPos() - m_startMovePos;
QPoint widgetPos = QApplication::activeWindow()->pos();
m_startMovePos = event->globalPos();
QApplication::activeWindow()->move(widgetPos.x() + movePoint.x(), widgetPos.y() + movePoint.y());
}
return QWidget::mouseMoveEvent(event);
}
function, but the result shows something wrong.
I have searched above two questions. But get nothing. And I'm curious that other applications can do just right both restore and move, suchlike Firefox web browser(which I'm typing on). So, there must be some way to make it work.

Qt this->update() is not entirely updating the widget

I created a simple widget with a button, a slot for the button, a resize event and a paint event.
I expect when I click on the button it draws an ellipse at a random position and the button disappears.
But I get: the ellipse is drawn and the button is not hidden after this->update.
Even stranger, when I uncomment the button->hide(); every time I click it draws a new eclipse but the old ellipses are still there. Something is wrong with updating and the paint event.
If I resize the window by dragging with the mouse the update of the paint event works as expected. Only the last ellipse stays and the button is hidden.
My Qt version is Qt_5_15_2_MinGW_32_bit
Here is the code of the widget:
PATrackSetter::PATrackSetter(QWidget *parent) : QWidget(parent){
button = new PAButton(this);
connect(button,SIGNAL(clicked(int, QString, QString)),this,SLOT(on_TileClicked(int, QString, QString)));
button->setFixedSize(100, 100);
button->move(0,0);
button->show();
}
void PATrackSetter::paintEvent(QPaintEvent *){
QPainter painter(this);
painter.setRenderHint(QPainter::Antialiasing);
QPen pen = QPen();
pen.setColor(Qt::yellow);
painter.setPen(pen);
painter.drawEllipse(100,rand() % 500 +10,5,5);
}
void PATrackSetter::resizeEvent(QResizeEvent *)
{
}
void PATrackSetter::on_TileClicked(int buttonID, QString buttonText, QString newButtonStatus){
button->hide();
this->update();
}
Can anyone see what I did wrong?
Edit:
I added more code to the project and I run into the same issue. I added the following lines into the MainWindow class and the updating inside the PATrackSetter widget doesn't work anymore as expected. I really dont understand why. But if I uncomment these lines it works again well.
QPalette paletteBGColor;
QBrush brush;
brush.setColor(Qt::black);
paletteBGColor.setBrush(QPalette::Background, brush);
this->setPalette(paletteBGColor);
Case closed.
If the button is not hidden then slot is not called. I guess you didn't put void on_TileClicked(int, QString, QString) in slots: section in header file, or signal/slot signatures don't match (in which case there must be warning in debug output in runtime).
When you are reimplementing paintEvent you should expect that every update on the QWidget, even manually or by the parent window, will call the paintEvent once. So, it's up to you to handle cleaning the previous state or draw on the previous drawings. The behavior you explained is quite normal.
It seems that you are not calling setGeometry on the PATrackSetter when you are instantiating it. So, in the update hierarchy, its size is not known and you should expect partial redraws and undefined behaviors.

Qml button press and hold does not trigger when moving mouse or finger

Pressing on Qml Button with mouse or finger(on touch enabled device) and moving too much will not emit pressAndHold() signal.
pressAndHold()
This signal is emitted when the button is interactively pressed and
held down by the user via touch or mouse.
Moving very few pixels would emit pressAndHold() signal but it seems the threshold is very small and it is very apparent problem on touch enabled device where finger naturally moves a little when pressing on button. Therefore pressAndHold() signal would not be emitted reliably.
Solution:
Set startDragDistance property to higher than default value(10)
QGuiApplication::styleHints()->setStartDragDistance(100);
Explanation:
Looking at the QQuickAbstractButton source code one can find method:
void QQuickAbstractButtonPrivate::handleMove(const QPointF &point)
void QQuickAbstractButtonPrivate::handleMove(const QPointF &point)
{
Q_Q(QQuickAbstractButton);
QQuickControlPrivate::handleMove(point);
setMovePoint(point);
q->setPressed(keepPressed || q->contains(point));
if (!pressed && autoRepeat)
stopPressRepeat();
else if (holdTimer > 0 && (!pressed || QLineF(pressPoint, point).length() > QGuiApplication::styleHints()->startDragDistance()))
stopPressAndHold();
}
When distance from starting point to moved point is greater than QGuiApplication::styleHints()->startDragDistance() threshold stopPressAndHold() is called cancelling press and hold action.

Problems changing the flags of a QWidget

I have a QWidget as the child of another within my application. The task consists of putting the internal widget in full screen mode and being able to see it again in normal mode with the same button. This partly I have managed to do it in the following way:
if(!isFullScreen())
{
setWindowFlags(windowFlags() | Qt::Window);
showFullScreen();
}
else
{
setWindowFlags(windowFlags() & ~Qt::Window);
showNormal();
activateWindow();
}
The problem arises when you return to see the widget in normal mode. Things that happen:
The mouse cursor stays with pointing hand cursor.
The button to change mode remains in hover state (the background color is changed when the mouse is over)
Passing the mouse through other widget controls does not change its appearance
I have to click on the widget to fix the behavior. It's as if the widget did not receive events of any kind or something like that. I tried calling setFocus () and it did not work. I have also tried to send an event by hand in the following way but it has not worked either:
QMouseEvent my_event(QEvent::MouseButtonPress, QPointF (0, 0), Qt :: NoButton, 0, 0);
QApplication::sendEvent(this, & my_event);
Any ideas?
Thanks.
Cannot reproduce your issue on Xubuntu with Qt5.9.4.
However I did the same in my last job, and it worked correctly on all platforms. It was something like this, I think:
if(!isFullScreen())
{
setParent(0);
showFullScreen();
}
else
{
orignalParentLayout->addWidget(this); // better: insert at correct position
showNormal();
}
For this you have to add some knowledge about the parent's layout though. You could try to detect that info before going into full screen mode, but it is probably not worth the effort.
You could also try:
if(!isFullScreen())
{
logicalParent = parentWidget();
setParent(0);
showFullScreen();
}
else
{
setParent(logicalParent);
showNormal();
}
If you have no layout. You might also want to store the geometry before going to full screen.

Moving object with mouse

I use Qt and I want to move some object with mouse. For example, user clicks on object and drag this object to another place of window. How I can do it?
I tried mouseMoveEvent:
void QDropLabel::mouseMoveEvent(QMouseEvent *ev)
{
this->move(ev->pos());
}
but unfortunately object moves very strange way. It jumps from place to place.
QDropLabel inherits QLabel. Also it has given a pixmap.
I tried to do it with different objects, but result is same.
Your movable widget must have a QPoint offset member. It will store a position of the cursor click relative to the widget's top left corner:
void DropLabel::mousePressEvent(QMouseEvent *event)
{
offset = event->pos();
}
On mouse move event you just move your widget in its parent coordinate system. Note that if you don't subtract offset from the cursor position, your widget will 'jump' so its top left corner will be just under the cursor.
void DropLabel::mouseMoveEvent(QMouseEvent *event)
{
if(event->buttons() & Qt::LeftButton)
{
this->move(mapToParent(event->pos() - offset));
}
}

Resources