GrabKeyboard() and grabMouse() - type of thing, but limited to the application window?



  • I have a number of widgets derived from QLineEdit and they are set to accept only certain type of input. On receiving invalid input the whole application should be blocked - meaning no other widget should be selectable by either keyboard or mouse - until the offending input is corrected.

    I have two questions, though if I solve the first the second can be forgotten (except if you are in a mood to educate me, which would be great).

    1. Can this be done without (re)implementing event handlers in each and every widget? I suppose/hope that it can and I just don't know how (I am new to Qt).

    I have tried with calling grabKeyboard() and grabMouse() on the offending widget, but that also blocks keyboard and mouse outside the application i.e. it blocks the whole desktop. That is too aggressive as user should be able to switch to another application and work in it as usual. If there is (simple) way to limit the effect of grabKeyboard() and grabMouse() only to the application window, it would be great to hear it.

    I also tried doing this using the already reimplemented myQLineEdit's event(QEvent*) handler and it works as it should for keyboard but not for the mouse. Curiously, the part of the code that corresponds to mouse clicks DOES get called but the result is as if it doesn't.

    Note: stateInvalid() returns true/false depending on whether there is a myQLineEdit with invalid input or not. It sits in the main window and is changed using signals.

    What happens: On invalid input in a myQLineEdit, stateInvalid() is set to true. Keyboard gets properly disabled by the handler. However, any other myQLineEdit I click on gets selected - even though the "Eating mouse press!" line prints out.

    Why is this? Who handles the mouse click besides this event handler?

    Thanks.

    @bool myQLineEdit::event(QEvent *e)
    {
    if (e->type() == QEvent::KeyPress)
    {
    // this part works as it should
    }
    else if (e->type()==QEvent::MouseButtonPress)
    {
    qDebug()<<"QLineEdit MouseButtonPress || state invalid = "<< stateInvalid()<<"\n";
    if (stateInvalid())
    {
    qDebug()<<"Eating mouse press!\n";
    return true;
    }
    else
    {
    qDebug()<<"Not eating mouse press!\n";
    QLineEdit::event(e);
    }
    }
    else QLineEdit::event(e);
    }@


  • Lifetime Qt Champion

    Hi,

    What would you consider a wrong input ?

    You could use validators on your QLineEdits so that you user can only enter valid values.

    Hope it helps



  • Hi SGaist,

    I am using QLineEdit's input validator and that part is not a problem, except in the sense that it still allows the user to select another widget within the application. But to answer your question, invalid input is anything that can't be converted to a double.
    If invalid input is entered, the event handler above prevents the user from doing anything using keyboard except fixing the input. Problem is the handler's mouse button press section, which gets called but does not do what I expect it to, which is to just throw the mouse press down the drain.


  • Lifetime Qt Champion

    Then why not use a "QDoubleSpinBox":http://doc.qt.io/qt-5/qdoublespinbox.html ?



  • Ok, I have to look at that and figure out what you have in mind.



  • QDoubleSpinBox can't accept exponentials, QLineEdit can, but I like the general idea and will remember it for situations where it could work.

    edit. Ok, I see now that it has a valueFromText and textFromValues functions, have to chech those out.


  • Lifetime Qt Champion

    What I have in mind is pretty simple: if you can avoid getting invalid input from users then don't let it happen.

    You might be interested by "this":http://www.matthiaspospiech.de/blog/2009/01/03/qt-spinbox-widget-with-scientific-notation/



  • [quote author="applefier" date="1423233714"]I have a number of
    I have tried with calling grabKeyboard() and grabMouse() on the offending widget, but that also blocks keyboard and mouse outside the application i.e. it blocks the whole desktop. That is too aggressive as user should be able to switch to another application and work in it as usual. If there is (simple) way to limit the effect of grabKeyboard() and grabMouse() only to the application window, it would be great to hear it.
    [/quote]

    What operating system do you use when it blocks complete desktop with grabbers ? linux + X11 ?



  • I know you can grab the mouse in Windows (don't remember the API calls necessary). It is useful for 3D application stuff such as rotating a cad window where the mouse may, and often does, venture outside of the window. I am not sure if you can do the same thing with the input focus though.

    Maybe a system modal dialog or something along those lines is what you are looking for? This will lock the system if the dialog is up.

    I think there are better ways to handle this. A wizard of some sort that will not move to the next stage if an input error is detected might be more user friendly.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.