39

I have a QTableWidget and would like that pressing CTRL while clicking on a column header marks the whole column. To get the column index is not a problem since there is a sectionPressed signal which gives me the current index of the column clicked. How can I get the state of any keyboard modifiers when a column is clicked?

NG_
  • 6,895
  • 7
  • 45
  • 67
tfl
  • 1,011
  • 2
  • 12
  • 21
  • This anwser was very helpfull [https://stackoverflow.com/questions/8772595/how-can-i-check-if-a-keyboard-modifier-is-pressed-shift-ctrl-or-alt](https://stackoverflow.com/questions/8772595/how-can-i-check-if-a-keyboard-modifier-is-pressed-shift-ctrl-or-alt) – MBV Dec 22 '21 at 22:55

5 Answers5

40

On Qt 4, try QApplication::keyboardModifiers().

The Qt 5 equivalent is QGuiApplication::keyboardModifiers().

Toby Speight
  • 27,591
  • 48
  • 66
  • 103
  • 2
    NOW I stumble upon this answer! After I rewrote everything as a messy sub-class so I could get at the `event` object :-) D'oh! – Freedom_Ben May 02 '13 at 17:38
  • Similar to @Freedom_Ben I was also looking at all the examples suggesting sub-classing or event-filter... but thanks to my persistence (may be it's laziness :P) that I found this answer. Works like a charm... EXACTLY as I wanted! Thanks Roku for his help! – zeFree May 09 '13 at 06:13
  • `keyboardModifiers()` isn't always accurate. `queryKeyboardModifiers()` is better, see [Martin Delille's answer](https://stackoverflow.com/a/25624550/4284627). – Donald Duck Mar 26 '18 at 16:29
  • 1
    If you want to know whether CTRL was pressed when the user clicked – rather than at the time your code calls the method to find out the modifier key state, which might be later – it sounds like `keyboardModifiers()` is correct, not `queryKeyboardModifiers()`, if I understand the doc correctly. – bhaller Nov 24 '19 at 01:11
  • 1
    I agree with @bhaller. `keyboardModifiers()` is better suited in this case. When I proposed my solution, my usecase was a little bit different: I wanted to know if the user was pressing a modifier key at the application startup. It could be after the last mouse click (the user clicking the application icon) so an explicit query was required in this case. – Martin Delille Nov 25 '19 at 08:12
13

If you are want to know the modifiers key state from a mouse click event, you can use QGuiApplication::keyboardModifiers() which will retrieve the key state during the last mouse event:

if(QGuiApplication::keyboardModifiers().testFlag(Qt::ControlModifier)) {
    // Do a few things
}

Otherwise, if you want to query explicitly the modifiers state you should use QGuiApplication::queryKeyboardModifiers(). This might be required in other use case like detecting a modifier key during the application startup.

Martin Delille
  • 11,360
  • 15
  • 65
  • 132
  • If you want to know whether CTRL was pressed when the user clicked – rather than at the time your code calls the method to find out the modifier key state, which might be later – it sounds like `keyboardModifiers()` is correct, not `queryKeyboardModifiers()`, if I understand the doc correctly. – bhaller Nov 24 '19 at 01:11
  • @bhaller I din't noticed the difference. I guess `keyboardModifiers()` is fine in this case because if the call is done within the `onClick()` event, it shouldn't be necessary to query again the keyboard modifiers. – Martin Delille Nov 25 '19 at 08:05
  • I updated my answer to explain the difference between the two solutions – Martin Delille Nov 25 '19 at 08:20
  • Hi! Is there something like QGuiApplication::keyboardModifiers which returns all the modifier keys in general, not what is pressed? – László Papp May 19 '22 at 09:47
11

The state of the keyboard modifier keys can be found by calling the modifiers() function, inherited from QInputEvent.

http://doc.qt.io/qt-5/qmouseevent.html

Christophe Weis
  • 2,518
  • 4
  • 28
  • 32
František Žiačik
  • 7,511
  • 1
  • 34
  • 59
  • I know but I have no object within the associated slot to sectionPressed other then the column index. No event, no sender, nothing. – tfl Jun 23 '10 at 08:50
  • Maybe you could save the modifiers state in mouseReleaseEvent which should occur before the signal. – František Žiačik Jun 23 '10 at 09:11
4

this is really annoying, I have to install an eventFilter and remove the sectionPressed handler

ui->tableWidget->horizontalHeader()->viewport()->installEventFilter(this);

Within the eventFilter I can check wether a key was pressed like so

bool MainWindow::eventFilter(QObject *object, QEvent *event)
{
    if(event->type() == QEvent::MouseButtonPress)
    {
        if(Qt::ControlModifier == QApplication::keyboardModifiers())
        {
            QMouseEvent *mouseEvent = static_cast<QMouseEvent *>(event);
            if(mouseEvent)
            {
                if(mouseEvent->button()== Qt::LeftButton)
                {
                    ui->tableWidget->selectColumn(ui->tableWidget->itemAt(mouseEvent->pos())->column());
                    return true;
                }
            }
        }
    }

    return QWidget::eventFilter(object,event);
}
tfl
  • 1,011
  • 2
  • 12
  • 21
3

This works for me.

if (QApplication::keyboardModifiers().testFlag(Qt::ControlModifier) == true) {
Dawoon Yi
  • 426
  • 3
  • 9