Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Qt user resize event ends (stops)

I have a QWidget and i need to do some actions (refresh a picture in widget) when resize event ends. How can i catch this action? I need to catch moment when user ENDs all his resize actions by releasing mouse button. It is not a good practice in my application to refresh image every pixel resized. It should calls only when mouse released and resize actions ends.

I am just tried to reimplement QMouseReleaseEvent to catch it, but it do not works when user presses on the border of widget to resize it. It means does not working in our situation.

Then i was tried to create my own QSizeGrip and insert it on the bottom of my widget, but reimplemented event QMouseReleaseEvent again did not work in it. Event did not generates any time user released mouse. I do not know why.

Anybody can help me with that problem?

Thanks in advance.

like image 663
fryme Avatar asked Oct 13 '11 12:10

fryme


People also ask

What is resize event in qwidget?

Resize events are sent to widgets that have been resized. The event handler QWidget::resizeEvent () receives resize events. See also QWidget::resize () and QWidget::setGeometry ().

How do I handle an event in Qt?

When you handle an event like we just did, you have the option to ACCEPT the event, or to IGNORE the event. When you accept the event, by calling the accept () method on your event parameter, you’re signaling to the Qt framework that you have dealt with the event and it won’t try to handle it in any other way.

When should I fire the resize event in jQuery?

Firing resize event only when resizing is finished. jQuery resize event is fired when the size of the browser’s window (viewport) changes as pointed out in jQuery documentation. Sometimes we need to execute functions which might take a while to execute or which might consume quite a few resources from the machine.

What are qmouseevent and qresizeevent?

For example there is an event for when someone clicks on a button : QMouseEvent, an event for when one of your widgets is resized QResizeEvent, an event for when your application is closed QCloseEvent and so on. They are a low level mechanism allowing you to control the look and the behavior of your classes and objects, especially widgets.


2 Answers

The timeout method is a decent idea, but if the user is resizing and then pauses for longer than the timer's interval then you end up not getting the true "user is done resizing the window" event. Setting the interval longer makes that situation less likely, but by doing that, you end up having a long delay between the time the user finished resizing and the time your function gets called. In my search for a solution, I found quite a few people solving it using the timer method, so apparently it's reliable enough for some use cases, but I think it's a bit hacky.

I like mhstnsc's idea, so after implementing it, I decided to add some code here that might be of use to someone trying to do something similar. You could easily adapt it to catch the "user is done moving the window" event by making a m_bUserIsMoving flag and overriding "void MainWindow::moveEvent(QMoveEvent* pEvent)". I'm using it to save a config file whenever the user finishes resizing or moving the window, so that the last position will always be saved even if the app is killed in an unclean manner.

// constructor
MainWindow::MainWindow(QWidget* pParent, Qt::WindowFlags flags) : QMainWindow(pParent, flags)
{
    m_bUserIsResizing = false;
    qApp->installEventFilter(this);
}

// this will be called when any event in the application occurs
bool MainWindow::eventFilter(QObject* pObj, QEvent* pEvent)
{
    // We need to check for both types of mouse release, because it can vary on which type happens when resizing.
    if ((pEvent->type() == QEvent::MouseButtonRelease) || (pEvent->type() == QEvent::NonClientAreaMouseButtonRelease)) {
        QMouseEvent* pMouseEvent = dynamic_cast<QMouseEvent*>(pEvent);
        if ((pMouseEvent->button() == Qt::MouseButton::LeftButton) && m_bUserIsResizing) {
            printf("Gotcha!\n");
            m_bUserIsResizing = false; // reset user resizing flag
        }
    }
    return QObject::eventFilter(pObj, pEvent); // pass it on without eating it
}

// override from QWidget that triggers whenever the user resizes the window
void MainWindow::resizeEvent(QResizeEvent* pEvent) { m_bUserIsResizing = true; }

It's slightly more complicated than the timer, but more robust.

like image 58
Ph0t0n Avatar answered Oct 19 '22 22:10

Ph0t0n


I've do it in this way:

  1. inherit my class from QWidget
  2. define private variable int timerId = 0
  3. overload QWidget::resizeEvent and QObject::timerEvent

void MapLoader::resizeEvent(QResizeEvent *){
    if (timerId){
        killTimer(timerId);
        timerId = 0;
    }
    timerId = startTimer(5000/*delay beetween ends of resize and your action*/);
}

void MapLoader::timerEvent(QTimerEvent *te){
    /*your actions here*/
    killTimer(te->timerId());
    timerId = 0;
}
like image 45
lord0lex Avatar answered Oct 19 '22 23:10

lord0lex