Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QLineEdit in modal QDialog: cannot enter text.
Forum Updated to NodeBB v4.3 + New Features

QLineEdit in modal QDialog: cannot enter text.

Scheduled Pinned Locked Moved Solved General and Desktop
6 Posts 3 Posters 1.2k Views 2 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • B Offline
    B Offline
    Bart_Vandewoestyne
    wrote on last edited by
    #1

    Using Qt 5.12.0, we have a modal QDialog window with three QLineEdits. Right
    after the modal dialog is shown, it is not possible to enter text in the
    QLineEdits. We also have code to bring up a virtual keyboard when
    right-clicking the line edit. It is not a virtual keyboard as described in
    http://doc.qt.io/qt-5/qtvirtualkeyboard-index.html, but rather a custom widget
    derived from QWidget. If we bring up the virtual keyboard widget and then
    close it again, we can enter text in the QLineEdit. So the opening and
    closing of the virtual keyboard widget seems to magically 'fix' the state of
    the line edit so that we can enter text.

    We observed a difference in behavior between the 'can enter text' and 'cannot
    enter text' situation. That difference occurs in the Qt 5.12.0 source file
    qguiapplication.cpp in the function

    void QGuiApplicationPrivate::processKeyEvent(QWindowSystemInterfacePrivate::KeyEvent *e)
    {
        ....
    
        // only deliver key events when we have a window, and no modal window is blocking this window
    
        if (window && !window->d_func()->blockedByModalWindow)
            QGuiApplication::sendSpontaneousEvent(window, &ev);
    
        ....
    }
    

    In the bad case (where the user can not enter text) we noticed that
    window->d_func()->blockedByModalWindow is true so that
    QGuiApplication::sendSpontaneousEvent(window, &ev) is not called.

    In the good case (where the user can enter text) we noticed that
    window->d_func()->blockedByModalWindow is false so that
    QGuiApplication::sendSpontaneousEvent(window, &ev) is called.

    I've found two Stackoverflow posts related to a similar problem, but for an older version of Qt:

    https://stackoverflow.com/questions/2180070/qdialog-doesnt-accept-text-input-if-modal (Qt 4.6 on Windows)
    https://stackoverflow.com/questions/7136760/qt-qdialog-issue-qlineedit-will-not-take-input (Qt 4.7.3)

    My questions are:

    1. Does anyone know if the behavior I am describing is related to a bug in Qt 5.12.0?

    2. Since window->d_func()->blockedByModalWindow is true in the 'cannot enter
      text' case, we think that the QDialog with the QLineEdit is blocked by
      some other modal window, but we cannot figure out which one. What could be a
      possible strategy to find out what other modal window is blocking our QDialog
      and line edit?

    1 Reply Last reply
    0
    • VRoninV Offline
      VRoninV Offline
      VRonin
      wrote on last edited by
      #2

      Can you post minimal complete example?

      My gut feeling is that you parented the linedits wrong but with no code is just guessing.

      "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
      ~Napoleon Bonaparte

      On a crusade to banish setIndexWidget() from the holy land of Qt

      1 Reply Last reply
      0
      • B Offline
        B Offline
        Bart_Vandewoestyne
        wrote on last edited by
        #3

        I was not able to trim this down to a complete minimal example yet (other priorities and the code is quite 'complicated'), but while debugging, we found out that our conclusion about 'the QDialog being blocked by a modal window' might be incorrect. When hitting the breakpoint mentioned in my first post, the function window->d_func() seems to return our application window in the case where the user cannot enter text (note that blockedByModalWindow is true):

        window->d_func()
        0x083bfd20 {...}
            [QWidgetWindowPrivate]: {...}
            QObjectPrivate: {extraData=0x082a9448 {userData={ size = 0 } propertyNames={ size = 0 } propertyValues={ size = 0 } ...} ...}
            surfaceType: RasterGLSurface (2)
            windowFlags: {i=-2013204479 }
            parentWindow: 0x00000000 <NULL>
            platformWindow: 0x02313ad0 {m_data={flags={i=134279169 } geometry={ x = 0, y = 0, width = 1920, height = 1080 } fullFrameMargins=...} ...}
            visible: true
            visibilityOnDestroy: false
            exposed: true
            requestedFormat: {d=0x023b0998 {ref={...} opts={i=0 } redBufferSize=-1 ...} }
            windowTitle: Our Super Duper Cool Application
            windowIcon: {d=0x02344598 {engine=0x0236bdb8 {pixmaps={ size = 1 } } ref={...} serialNum=1 ...} }
            geometry: { x = 0, y = 0, width = 1920, height = 1080 }
            windowState: {i=4 }
            visibility: FullScreen (5)
            resizeEventPending: false
            receivedExpose: true
            positionPolicy: WindowFrameExclusive (1)
            positionAutomatic: true
            contentOrientation: PrimaryOrientation (0)
            opacity: 1.0000000000000000
            mask: {d=0x02e244f4 {Qt5Guid.dll!QRegion::QRegionData QRegion::shared_empty} {ref={atomic={_q_value=-1 } } ...} }
            minimumSize: { width = 1023, height = 841 }
            maximumSize: { width = 16777215, height = 16777215 }
            baseSize: { width = 0, height = 0 }
            sizeIncrement: { width = 0, height = 0 }
            modality: NonModal (0)
            blockedByModalWindow: true
            updateRequestPending: false
            transientParent: guarded pointer to subclass of QObject of type "QWindow"
            topLevelScreen: guarded pointer to subclass of QObject of type "QScreen"
            cursor: {d=0x023129c8 {ref={...} cshape=ArrowCursor (0) bm=0x00000000 <NULL> ...} }
            hasCursor: true
            compositing: false
            lastComposeTime: {t1=-9223372036854775808 t2=-9223372036854775808 }
        

        while in the case where the user can enter text, we have our dialog window when we hit the mentioned breakpoint (note that blockedByModalWindow) is false:

        window->d_func()
        0x0899a4b8 {...}
            [QWidgetWindowPrivate]: {...}
            QObjectPrivate: {extraData=0x0885a168 {userData={ size = 0 } propertyNames={ size = 0 } propertyValues={ size = 0 } ...} ...}
            surfaceType: RasterGLSurface (2)
            windowFlags: {i=2051 }
            parentWindow: 0x00000000 <NULL>
            platformWindow: 0x08916888 {m_data={flags={i=2051 } geometry={ x = 785, y = 400, width = 350, height = 280 } fullFrameMargins=...} ...}
            visible: true
            visibilityOnDestroy: false
            exposed: true
            requestedFormat: {d=0x0237a348 {ref={...} opts={i=0 } redBufferSize=-1 ...} }
            windowIcon: {d=0x02344598 {engine=0x0236bdb8 {pixmaps={ size = 1 } } ref={...} serialNum=1 ...} }
            geometry: { x = 785, y = 400, width = 350, height = 280 }
            windowState: {i=0 }
            visibility: Windowed (2)
            resizeEventPending: false
            receivedExpose: true
            positionPolicy: WindowFrameInclusive (0)
            positionAutomatic: false
            contentOrientation: PrimaryOrientation (0)
            opacity: 1.0000000000000000
            mask: {d=0x02e244f4 {Qt5Guid.dll!QRegion::QRegionData QRegion::shared_empty} {ref={atomic={_q_value=-1 } } ...} }
            minimumSize: { width = 350, height = 280 }
            maximumSize: { width = 16777215, height = 16777215 }
            baseSize: { width = 0, height = 0 }
            sizeIncrement: { width = 0, height = 0 }
            modality: ApplicationModal (2)
            blockedByModalWindow: false
            updateRequestPending: false
            transientParent: guarded pointer to subclass of QObject of type "QWindow"
            topLevelScreen: guarded pointer to subclass of QObject of type "QScreen"
            cursor: {d=0x02312568 {ref={...} cshape=IBeamCursor (4) bm=0x00000000 <NULL> ...} }
            hasCursor: true
            compositing: false
            lastComposeTime: {t1=-9223372036854775808 t2=-9223372036854775808 }
        

        For now, this is all I can say. I'm still in debugging modus :-) Any suggestions welcome!

        kshegunovK 1 Reply Last reply
        0
        • B Bart_Vandewoestyne

          I was not able to trim this down to a complete minimal example yet (other priorities and the code is quite 'complicated'), but while debugging, we found out that our conclusion about 'the QDialog being blocked by a modal window' might be incorrect. When hitting the breakpoint mentioned in my first post, the function window->d_func() seems to return our application window in the case where the user cannot enter text (note that blockedByModalWindow is true):

          window->d_func()
          0x083bfd20 {...}
              [QWidgetWindowPrivate]: {...}
              QObjectPrivate: {extraData=0x082a9448 {userData={ size = 0 } propertyNames={ size = 0 } propertyValues={ size = 0 } ...} ...}
              surfaceType: RasterGLSurface (2)
              windowFlags: {i=-2013204479 }
              parentWindow: 0x00000000 <NULL>
              platformWindow: 0x02313ad0 {m_data={flags={i=134279169 } geometry={ x = 0, y = 0, width = 1920, height = 1080 } fullFrameMargins=...} ...}
              visible: true
              visibilityOnDestroy: false
              exposed: true
              requestedFormat: {d=0x023b0998 {ref={...} opts={i=0 } redBufferSize=-1 ...} }
              windowTitle: Our Super Duper Cool Application
              windowIcon: {d=0x02344598 {engine=0x0236bdb8 {pixmaps={ size = 1 } } ref={...} serialNum=1 ...} }
              geometry: { x = 0, y = 0, width = 1920, height = 1080 }
              windowState: {i=4 }
              visibility: FullScreen (5)
              resizeEventPending: false
              receivedExpose: true
              positionPolicy: WindowFrameExclusive (1)
              positionAutomatic: true
              contentOrientation: PrimaryOrientation (0)
              opacity: 1.0000000000000000
              mask: {d=0x02e244f4 {Qt5Guid.dll!QRegion::QRegionData QRegion::shared_empty} {ref={atomic={_q_value=-1 } } ...} }
              minimumSize: { width = 1023, height = 841 }
              maximumSize: { width = 16777215, height = 16777215 }
              baseSize: { width = 0, height = 0 }
              sizeIncrement: { width = 0, height = 0 }
              modality: NonModal (0)
              blockedByModalWindow: true
              updateRequestPending: false
              transientParent: guarded pointer to subclass of QObject of type "QWindow"
              topLevelScreen: guarded pointer to subclass of QObject of type "QScreen"
              cursor: {d=0x023129c8 {ref={...} cshape=ArrowCursor (0) bm=0x00000000 <NULL> ...} }
              hasCursor: true
              compositing: false
              lastComposeTime: {t1=-9223372036854775808 t2=-9223372036854775808 }
          

          while in the case where the user can enter text, we have our dialog window when we hit the mentioned breakpoint (note that blockedByModalWindow) is false:

          window->d_func()
          0x0899a4b8 {...}
              [QWidgetWindowPrivate]: {...}
              QObjectPrivate: {extraData=0x0885a168 {userData={ size = 0 } propertyNames={ size = 0 } propertyValues={ size = 0 } ...} ...}
              surfaceType: RasterGLSurface (2)
              windowFlags: {i=2051 }
              parentWindow: 0x00000000 <NULL>
              platformWindow: 0x08916888 {m_data={flags={i=2051 } geometry={ x = 785, y = 400, width = 350, height = 280 } fullFrameMargins=...} ...}
              visible: true
              visibilityOnDestroy: false
              exposed: true
              requestedFormat: {d=0x0237a348 {ref={...} opts={i=0 } redBufferSize=-1 ...} }
              windowIcon: {d=0x02344598 {engine=0x0236bdb8 {pixmaps={ size = 1 } } ref={...} serialNum=1 ...} }
              geometry: { x = 785, y = 400, width = 350, height = 280 }
              windowState: {i=0 }
              visibility: Windowed (2)
              resizeEventPending: false
              receivedExpose: true
              positionPolicy: WindowFrameInclusive (0)
              positionAutomatic: false
              contentOrientation: PrimaryOrientation (0)
              opacity: 1.0000000000000000
              mask: {d=0x02e244f4 {Qt5Guid.dll!QRegion::QRegionData QRegion::shared_empty} {ref={atomic={_q_value=-1 } } ...} }
              minimumSize: { width = 350, height = 280 }
              maximumSize: { width = 16777215, height = 16777215 }
              baseSize: { width = 0, height = 0 }
              sizeIncrement: { width = 0, height = 0 }
              modality: ApplicationModal (2)
              blockedByModalWindow: false
              updateRequestPending: false
              transientParent: guarded pointer to subclass of QObject of type "QWindow"
              topLevelScreen: guarded pointer to subclass of QObject of type "QScreen"
              cursor: {d=0x02312568 {ref={...} cshape=IBeamCursor (4) bm=0x00000000 <NULL> ...} }
              hasCursor: true
              compositing: false
              lastComposeTime: {t1=-9223372036854775808 t2=-9223372036854775808 }
          

          For now, this is all I can say. I'm still in debugging modus :-) Any suggestions welcome!

          kshegunovK Offline
          kshegunovK Offline
          kshegunov
          Moderators
          wrote on last edited by
          #4

          Two things captured my interest:

          1. The flags in the first case:
          windowFlags: {i=-2013204479 }
          

          Is very suspicious, as the high-order bit is set only for a very specific flags. Not to mention that value sets a whole lot of bits that I don't believe should be set.

          1. The modality:
            First case:
          modality: NonModal (0)
          

          Second case:

          modality: ApplicationModal (2)
          

          Ideas:

          1. Check if the object is correct in the first case, and if there's some flag manipulation done on it, it may be wrong.
          2. Check why the discrepancy between case 1 and 2 between the modality. It suggests that the focus was captured by another widget/window in the first case (as you suspected).

          Read and abide by the Qt Code of Conduct

          1 Reply Last reply
          2
          • B Offline
            B Offline
            Bart_Vandewoestyne
            wrote on last edited by Bart_Vandewoestyne
            #5

            We were able to track down the problem. The person who solved the issue used the following commit message:

            This seems to be a conflict between grabKeyboard() and showModal(). Previously we did widget->grabKeyboard() before moving
            the widget to a new (modal) QDialog. This made the keyevents go to the wrong window in Qt 5. By moving widget->grabKeyboard() 
            after adding the widget to the modal QDialog, everything seems to be OK.
            

            Before, we were using Qt 4.8.7 and this problem did not occur. It was only until after our switch to Qt 5.11.3 (and later 5.12.0) that this problem occurred. So apparently, somewhere between Qt 4.8.7 and Qt 5.11.3 there is a change in behavior for the QWidget::grabKeyboard() method in combination with modality (or we were doing something wrong and were just lucky in 4.8.7)?

            kshegunovK 1 Reply Last reply
            0
            • B Bart_Vandewoestyne

              We were able to track down the problem. The person who solved the issue used the following commit message:

              This seems to be a conflict between grabKeyboard() and showModal(). Previously we did widget->grabKeyboard() before moving
              the widget to a new (modal) QDialog. This made the keyevents go to the wrong window in Qt 5. By moving widget->grabKeyboard() 
              after adding the widget to the modal QDialog, everything seems to be OK.
              

              Before, we were using Qt 4.8.7 and this problem did not occur. It was only until after our switch to Qt 5.11.3 (and later 5.12.0) that this problem occurred. So apparently, somewhere between Qt 4.8.7 and Qt 5.11.3 there is a change in behavior for the QWidget::grabKeyboard() method in combination with modality (or we were doing something wrong and were just lucky in 4.8.7)?

              kshegunovK Offline
              kshegunovK Offline
              kshegunov
              Moderators
              wrote on last edited by kshegunov
              #6

              @Bart_Vandewoestyne said in QLineEdit in modal QDialog: cannot enter text.:

              So apparently, somewhere between Qt 4.8.7 and Qt 5.11.3 there is a change in behavior for the QWidget::grabKeyboard() method in combination with modality

              grabKeyboard is the ultimate "modality" and is very invasive. If you're using it (regularly) it probably means you are doing something you shouldn't be.

              (or we were doing something wrong and were just lucky in 4.8.7)?

              It is possible. No way to tell beside boiling it down to an MRE which can be dissected.

              Read and abide by the Qt Code of Conduct

              1 Reply Last reply
              1

              • Login

              • Login or register to search.
              • First post
                Last post
              0
              • Categories
              • Recent
              • Tags
              • Popular
              • Users
              • Groups
              • Search
              • Get Qt Extensions
              • Unsolved