Tutorial :Qt Application: Simulating modal behaviour (enable/disable user input)



Question:

I am currently working on an application that launches separate processes which display additional dialogs. The feature I am trying to implement is simulating modal behavior of these dialogs. More specifically, I need the application to stop processing all input, both mouse and keyboard, when the dialog is launched, and resume when it's closed.

It is not so important for the dialog to remain on top of the application, although if you can suggest how to do that without resorting to Always-On-Top behavior, that would be nice as well.

To note, the application is compiled under both Windows and Linux. Also, it is not an option to launch the dialogs directly. They are in separate executables. Also the application is a pretty complex piece of software, so disabling widgets individually is not an option, or at least a not very viable one.

I found lock() and unlock() functions in QApplication class in Qt 3.3. We are currently using Qt 4.5, which doesn't seem to have that API. As a matter of fact, Qt 4.5 QApplication class doesn't seem to provide access to the Event Loop either.

To summarize: How do I disable/enable user input in a Qt Application, both mouse and keyboard shortcuts?


Solution:1

To get full access to the application wide events, use QObject::installEventFilter() or QCoreApplication::setEventFilter() on your application object.
If your filter function returns true, Qt stops further processing of the event.

To not get too platform specific with the forwarding of the events to your other applications, i'd go for a suitable IPC mechanism.


Solution:2

gj already proposed this solution but I thought I'd paste my implementation just for reference:

Implement a filter class that will absorb user input actions.

class BusyAppFilter : public QObject  {  protected:      bool eventFilter( QObject *obj, QEvent *event );  };      bool BusyAppFilter::eventFilter(QObject *obj, QEvent *event)  {      switch ( event->type() )      {      case QEvent::KeyPress:      case QEvent::KeyRelease:      case QEvent::MouseButtonPress:      case QEvent::MouseButtonDblClick:      case QEvent::MouseMove:      case QEvent::HoverEnter:      case QEvent::HoverLeave:      case QEvent::HoverMove:      case QEvent::DragEnter:      case QEvent::DragLeave:      case QEvent::DragMove:      case QEvent::Drop:          return true;      default:          return QObject::eventFilter( obj, event );      }  }  

Then place this code your QApplication class:

QCursor busyCursor( Qt::WaitCursor );  setOverrideCursor( busyCursor );    BusyAppFilter filter;  installEventFilter( &filter ) ;    //... do the process stuff ...    removeEventFilter( &filter );    restoreOverrideCursor();  


Solution:3

As an alternative answer, you can create your own event loop and start running it if necessary. You would need to create a QEventLoop object, connect a signal from another process to its quit() slot (such as from a QProcess that you are running your other program in), then exec() the loop. If I read things correctly, nothing will be handled by your main event loop while that loop is running.


Note:If u also have question or solution just comment us below or mail us on toontricks1994@gmail.com
Previous
Next Post »