Search code examples
user-interfaceqtmenucopy-paste

How to implement the "Edit" menu with "Undo", "Cut", "Paste" and "Copy"?


Greetings,

for one of my applications I'm trying to implement an "Edit" menu. This menu usually has the standard-entries Undo, Cut, Copy and Paste.

This menu is not there by default, and users seem to expect it especially on Mac OS X.

Is there a an easier way of implementing this, without doing so in every widget manually? Since most widgets have the copy/paste/undo mechanism already implemented via shortcuts, I'd like to provide a few simple menu actions that call them as well.

The actions should call whatever widget has the focus first, then they should pass the events upwards the object chain, I guess.

I'm using Qt 4.6 on Windows, Linux and Mac OS X.

Thanks!


Solution

  • It's easy enough to accomplish half of the necessary functionality. Just create the Edit menu, along with the necessary QActions (copy/paste/undo/etc.) in your main window class and connect them to slots. In the slots, emulate the correct key press and release events (e.g. Ctrl+C for Copy) and send them to the currently focused widget. In code, something like this:

    MainWindow::MainWindow(...)
    {
        ...
        connect( actionCopy, SIGNAL( triggered()), SLOT( copy()));
        ...
    }
    ...
    void MainWindow::copy()
    {
        QWidget* focused = QApplication::focusWidget();
        if( focused != 0 )
        {
            QApplication::postEvent( focused,
                                     new QKeyEvent( QEvent::KeyPress,
                                                    Qt::Key_C,
                                                    Qt::ControlModifier ));
            QApplication::postEvent( focused,
                                     new QKeyEvent( QEvent::KeyRelease,
                                                    Qt::Key_C,
                                                    Qt::ControlModifier ));
    }
    

    Of course, this is quite a hack. You need to modify the code for each target platform, changing the keyboard shortcuts to the correct ones, and it might happen that a widget that receives focus does something quiet unexpected with Ctrl+C. The worst downside in this method, in my opinion, is that you cannot properly control the enabled state of the Edit menu items. It is not possible to query from a generic widget whether a copy or paste operation would be possible or not.

    I am unable to find a real solution to this problem - and would be surprised to find out that one exists - as the copy/paste functionality is generally hidden inside the class' code and not exposed through any standard set of signals/slots. After tonight's experiments with the functionality, I have decided to just forget having an Edit menu from my application and expect the users to know the keyboard shortcuts, or use the context sensitive menus.