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. "keyPressEvent" is (sometimes) not called after DragDrop
Forum Updated to NodeBB v4.3 + New Features

"keyPressEvent" is (sometimes) not called after DragDrop

Scheduled Pinned Locked Moved Solved General and Desktop
5 Posts 2 Posters 1.2k Views
  • 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.
  • tomwebT Offline
    tomwebT Offline
    tomweb
    wrote on last edited by
    #1

    Hello,
    i want to drag items from a table, but only when i press ALT.
    Without i want only easy selection.

    My solution:
    void Cxy::keyPressEvent(QKeyEvent *event)
    { if(event->key() == Qt::Key_Alt) { gotable->setDragEnabled(true); }
    }
    void Cxy::keyReleaseEvent(QKeyEvent *event)
    { if(event->key() == Qt::Key_Alt) { gotable->setDragEnabled(false); }
    }

    works, but i often loose "keyReleaseEvent" when i drop the content in another program.
    My solution: a retriggered timer till the windows function "GetKeyState" says "no more ALT". Works perfect.

    But i still have a problem with "keyPressEvent".
    This works fine: (A) 1. press ALT, 2. drag 3. drop 4. release ALT
    This also: (B) 1. press ALT 2. drag 3. release ALT 4. drop in another program (my program looses focus)
    This also: (C) 1. press ALT 2. drag 3. release ALT 4. drop in my own program

    BUT, in case (C) qt don't call "keyPressEvent" when i press ALT next time.
    In this single case i have to press ALT 2 times, only the second time i get a "keyPressEvent"
    I even can press other keys, they are detected(!), but when i press ALT after (C) (and even after pressing other keys), the first pressed ALT has no effect.
    Seems that only the ALT key is locked once after (C).

    Any idea?
    I could use "GetKeyState" again, but then i have to poll it permanently and waste many cpu-time...

    tomwebT raven-worxR 2 Replies Last reply
    0
    • tomwebT tomweb

      Hello,
      i want to drag items from a table, but only when i press ALT.
      Without i want only easy selection.

      My solution:
      void Cxy::keyPressEvent(QKeyEvent *event)
      { if(event->key() == Qt::Key_Alt) { gotable->setDragEnabled(true); }
      }
      void Cxy::keyReleaseEvent(QKeyEvent *event)
      { if(event->key() == Qt::Key_Alt) { gotable->setDragEnabled(false); }
      }

      works, but i often loose "keyReleaseEvent" when i drop the content in another program.
      My solution: a retriggered timer till the windows function "GetKeyState" says "no more ALT". Works perfect.

      But i still have a problem with "keyPressEvent".
      This works fine: (A) 1. press ALT, 2. drag 3. drop 4. release ALT
      This also: (B) 1. press ALT 2. drag 3. release ALT 4. drop in another program (my program looses focus)
      This also: (C) 1. press ALT 2. drag 3. release ALT 4. drop in my own program

      BUT, in case (C) qt don't call "keyPressEvent" when i press ALT next time.
      In this single case i have to press ALT 2 times, only the second time i get a "keyPressEvent"
      I even can press other keys, they are detected(!), but when i press ALT after (C) (and even after pressing other keys), the first pressed ALT has no effect.
      Seems that only the ALT key is locked once after (C).

      Any idea?
      I could use "GetKeyState" again, but then i have to poll it permanently and waste many cpu-time...

      tomwebT Offline
      tomwebT Offline
      tomweb
      wrote on last edited by
      #2

      I guess, when Drag is in progress, Qt does not provide key-events at all.

      Seems that key-handling is not the the main strenght from Qt, so i wrote my own key-handler by using
      original windows funktion SetWindowsHookEx(WH_KEYBOARD_LL, myLowLevelKeyboardProc, NULL, 0);
      Not portable, of course, but it works perfect in all cases without the need to program timers etc.
      But i am still open for better soulutions...

      1 Reply Last reply
      0
      • tomwebT tomweb

        Hello,
        i want to drag items from a table, but only when i press ALT.
        Without i want only easy selection.

        My solution:
        void Cxy::keyPressEvent(QKeyEvent *event)
        { if(event->key() == Qt::Key_Alt) { gotable->setDragEnabled(true); }
        }
        void Cxy::keyReleaseEvent(QKeyEvent *event)
        { if(event->key() == Qt::Key_Alt) { gotable->setDragEnabled(false); }
        }

        works, but i often loose "keyReleaseEvent" when i drop the content in another program.
        My solution: a retriggered timer till the windows function "GetKeyState" says "no more ALT". Works perfect.

        But i still have a problem with "keyPressEvent".
        This works fine: (A) 1. press ALT, 2. drag 3. drop 4. release ALT
        This also: (B) 1. press ALT 2. drag 3. release ALT 4. drop in another program (my program looses focus)
        This also: (C) 1. press ALT 2. drag 3. release ALT 4. drop in my own program

        BUT, in case (C) qt don't call "keyPressEvent" when i press ALT next time.
        In this single case i have to press ALT 2 times, only the second time i get a "keyPressEvent"
        I even can press other keys, they are detected(!), but when i press ALT after (C) (and even after pressing other keys), the first pressed ALT has no effect.
        Seems that only the ALT key is locked once after (C).

        Any idea?
        I could use "GetKeyState" again, but then i have to poll it permanently and waste many cpu-time...

        raven-worxR Offline
        raven-worxR Offline
        raven-worx
        Moderators
        wrote on last edited by
        #3

        @tomweb
        a way cleaner approach instead of toggling the drag-enabled property like you do, would be to override QAbstractItemView::startDrag() and check if the ALT key is pressed - using QApplication::keyboardModifiers().

        Assuming Cxy is subclassing QAbstractItemView

        void Cxy::startDrag(Qt::DropActions supportedActions)
        {
            if( !(QApplication::keyboardModifiers() & Qt::AltModifier) )
                 return;
        
            QModelIndexList selectedIndexes = this->getSelectedDraggableIndexes();  // need to be implemented by yourself
            if (selectedIndexes .count() > 0)
            {
                QMimeData *data = this->model()->mimeData(selectedIndexes);
                if ( !data )
                    return;
        
                QDrag *drag = new QDrag(this);
                drag->setPixmap(...);
                drag->setMimeData(data);
                drag->setHotSpot(...);
                Qt::DropAction defaultDropAction = Qt::IgnoreAction;
                if (this->defaultDropAction() != Qt::IgnoreAction && (supportedActions & this->defaultDropAction()))
                    defaultDropAction = this->defaultDropAction();
                else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
                    defaultDropAction = Qt::CopyAction;
                drag->exec(supportedActions, defaultDropAction);
                ....
            }
        }
        

        --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
        If you have a question please use the forum so others can benefit from the solution in the future

        tomwebT 1 Reply Last reply
        3
        • raven-worxR raven-worx

          @tomweb
          a way cleaner approach instead of toggling the drag-enabled property like you do, would be to override QAbstractItemView::startDrag() and check if the ALT key is pressed - using QApplication::keyboardModifiers().

          Assuming Cxy is subclassing QAbstractItemView

          void Cxy::startDrag(Qt::DropActions supportedActions)
          {
              if( !(QApplication::keyboardModifiers() & Qt::AltModifier) )
                   return;
          
              QModelIndexList selectedIndexes = this->getSelectedDraggableIndexes();  // need to be implemented by yourself
              if (selectedIndexes .count() > 0)
              {
                  QMimeData *data = this->model()->mimeData(selectedIndexes);
                  if ( !data )
                      return;
          
                  QDrag *drag = new QDrag(this);
                  drag->setPixmap(...);
                  drag->setMimeData(data);
                  drag->setHotSpot(...);
                  Qt::DropAction defaultDropAction = Qt::IgnoreAction;
                  if (this->defaultDropAction() != Qt::IgnoreAction && (supportedActions & this->defaultDropAction()))
                      defaultDropAction = this->defaultDropAction();
                  else if (supportedActions & Qt::CopyAction && dragDropMode() != QAbstractItemView::InternalMove)
                      defaultDropAction = Qt::CopyAction;
                  drag->exec(supportedActions, defaultDropAction);
                  ....
              }
          }
          
          tomwebT Offline
          tomwebT Offline
          tomweb
          wrote on last edited by
          #4

          Hello @raven-worx ,
          thank you very much for this hint.
          First you confused me a little bit with "subclassing QAbstractItemView".
          I didn't find how to subclass "QAbstractItemView".
          In effect, i only had to extended "myQTableWidget"
          in Header:
          bool useAltKey; // DragDrop with ALT on/off
          void startDrag(Qt::DropActions supportedActions);
          and in implementation:
          void myQTableWidget::startDrag(Qt::DropActions supportedActions)
          { if( useAltKey && (!(QApplication::keyboardModifiers() & Qt::AltModifier)) ) { return; }
          QTableWidget::startDrag( supportedActions);
          }

          Works perfect, and it's even easier to turn on/off this feature. Again thank you.

          raven-worxR 1 Reply Last reply
          0
          • tomwebT tomweb

            Hello @raven-worx ,
            thank you very much for this hint.
            First you confused me a little bit with "subclassing QAbstractItemView".
            I didn't find how to subclass "QAbstractItemView".
            In effect, i only had to extended "myQTableWidget"
            in Header:
            bool useAltKey; // DragDrop with ALT on/off
            void startDrag(Qt::DropActions supportedActions);
            and in implementation:
            void myQTableWidget::startDrag(Qt::DropActions supportedActions)
            { if( useAltKey && (!(QApplication::keyboardModifiers() & Qt::AltModifier)) ) { return; }
            QTableWidget::startDrag( supportedActions);
            }

            Works perfect, and it's even easier to turn on/off this feature. Again thank you.

            raven-worxR Offline
            raven-worxR Offline
            raven-worx
            Moderators
            wrote on last edited by
            #5

            @tomweb
            indeed...this is easier. :)

            --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
            If you have a question please use the forum so others can benefit from the solution in the future

            1 Reply Last reply
            0

            • Login

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