Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

How to catch Ctrl+C on a widget?



  • Hi everyone! I have a treeview and I wrote an eventfilter that catches Ctrl+C combination:

    @ if (event->type() == QEvent::KeyPress) {
    QKeyEvent *ke = static_cast<QKeyEvent *>(event);

    if (ke->matches(QKeySequence::Copy)) {
    if (copyCurrentValue()) {
    event->accept();
    } e.t.c.@

    When I push Ctrl+Ins it works nice, but if I push Ctrl+C then ke->key() returns 16777249 keycode.

    Any ideas?



  • Have you tried overriding keyPressEvent, the code below works for me on a QMainWindow:

    @void MainWindow::keyPressEvent(QKeyEvent *e) {
    if(e->type() == QKeyEvent::KeyPress) {
    if(e->matches(QKeySequence::Copy)) {
    setWindowTitle("aa"); // when Ctrl+C is pressed window title changes to aa (for demo purposes)
    } else {
    setWindowTitle("bb"); // when other keys are pressed, window title changes to bb (for demo purposes)
    }
    }
    }@



  • you can try QList<QKeySequence> QKeySequence::keyBindings ( StandardKey key ) function to retrieve key bindings appropriate to your platform. Maybe your platform has only (ctrl+ins) binding.



  • I have tried keyBindings function and it returns Ctrl+C and Ctrl+Ins. Milot Shala, I did it, but the result was the same as with eventFilter :(

    P.S. In headerview Ctrl+C works, but Ctrl+Ins doesn't works. I don't understand what is it..



  • [quote author="kibsoft" date="1281701124"]I have tried keyBindings function and it returns Ctrl+C and Ctrl+Ins. Milot Shala, I did it, but the result was the same as with eventFilter :(

    P.S. In headerview Ctrl+C works, but Ctrl+Ins doesn't works. I don't understand what is it..[/quote]

    Where are you overriding the keyPressEvent virtual method?

    I modified mine when I press Ctrl+C to set the Window title to currently selected tree view node such as in picture below (I am using QFileSystemModel):

    !http://web7.twitpic.com/img/144954784-8f19fe179f40f269283c021d8028ac42.4c6541d0-full.png(window)!

    and the code is almost the same:

    @void MainWindow::keyPressEvent(QKeyEvent *e) {
    if(e->type() == QKeyEvent::KeyPress) {
    if(e->matches(QKeySequence::Copy)) {
    QString a = ui->treeView->currentIndex().model()->data(ui->treeView->currentIndex()).toString();
    setWindowTitle(a);
    e->accept();
    }
    }
    QMainWindow::keyPressEvent(e);
    }@



  • I have just tried to create new app and it works correct there. So this bug somewhere in the current project. I'll look. Thank you Milot :)



  • You are welcome kibsoft :)



  • KeyEvent's modifiers() returns Qt::ControlModifier and key() returns Qt::Key_Control when I push Ctrl+C..It is so strange..



  • bq. KeyEvent’s modifiers() returns Qt::ControlModifier and key() returns Qt::Key_Control when I push Ctrl+C..It is so strange..

    Just in case anyone finds this old post in a search (as I did), probably what confused kibsoft was that a keyPressEvent handler gets multiple events for a multi-key input. When the user hits control-x, the handler sees the above code meaning "control was pressed". Then immediately after comes another event with ControlModifier set and a key value of x.

    If the input is ctl-alt-x, then you would see three events as the user mashes the keys. This is why to test the event with matches() and ignore all that don't match.



  • I stumbled on this topic doing a google search about how to catch Ctrl-c on a gui app (for instance a gui program simulating a Ctrl-c interrupt like a terminal emulater), and after doing some research came up with this for Qt5 which is a bit different because Ctrl-c on a Mac is not equal to: event->matches(QKeySequence::Copy).

    If you are simulating a standard "Copy" content key (like word processor/text editor cut/copy/paste) combo then do indeed use event->matches(QKeySequence::Copy) but if you are trying to detect an actual Ctrl-c (like Ctrl-c terminal program interrupt) and you want something portable between Mac OS and something else (tested on both Mac OS High Sierra and Linux/Ubuntu 18.04):

    // Respond to Ctrl-c:
    void SomeWidget::keyPressEvent(QKeyEvent *event)
    {
        // the MetaModifier is actually the control button on Mac OS X (at least on recent Mac OSes. Tested on High Sierra)
        #ifdef Q_OS_MAC  
        // if compiling on Mac OS...
        if (event->key()==Qt::Key_C && (QGuiApplication::keyboardModifiers() & Qt::MetaModifier))
        #else 
        // If compiling on Linux (tested on Ubuntu 18.04), Windows, everything else...
        if (event->key()==Qt::Key_C && (QGuiApplication::keyboardModifiers() & Qt::ControlModifier))
        #endif
        {
            // Ctrl-c hit, do something here to process the key combo
        }
    }
    

Log in to reply