c++qtqmessageboxclipboard-interaction

In QMessageBox, how do I add to the text copied by Ctrl-C?


Using Qt, C++ on Windows, Ctrl-C copies a selection of text that includes the title, message, and so forth from a QMessageBox. I have added some additional fields and would like to add some custom text to the information copied from the standard QMessageBox from these fields. What do I override in QMessageBox to allow me to grab the text that is already being created and add my own text to it?


Solution

  • You need to reimplement QMessageBox and all functions you want to use. Here is minimal example:

    custommessagebox.h

    #include <QMessageBox>
    #include <QShortcut>
    
    class CustomMessageBox : public QMessageBox
    {
        Q_OBJECT
    public:
        explicit CustomMessageBox(QWidget *parent = 0);
        CustomMessageBox(Icon icon, const QString &title, const QString &text,
                    StandardButtons buttons = NoButton, QWidget *parent = Q_NULLPTR,
                    Qt::WindowFlags flags = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint);
        static StandardButton information(QWidget *parent, const QString &title,
             const QString &text, StandardButtons buttons = Ok,
             StandardButton defaultButton = NoButton);
    
    protected:
        void keyPressEvent(QKeyEvent *e);
    };
    

    custommessagebox.cpp

    #include "custommessagebox.h"
    #include <QClipboard>
    #include <QApplication>
    #include <QKeyEvent>
    #include <QDialogButtonBox>
    
    static QMessageBox::StandardButton showNewMessageBox(QWidget *parent,
        QMessageBox::Icon icon,
        const QString& title, const QString& text,
        QMessageBox::StandardButtons buttons,
        QMessageBox::StandardButton defaultButton)
    {
        CustomMessageBox msgBox(icon, title, text, QMessageBox::NoButton, parent);
        QDialogButtonBox *buttonBox = msgBox.findChild<QDialogButtonBox*>();
        Q_ASSERT(buttonBox != 0);
    
        uint mask = QMessageBox::FirstButton;
        while (mask <= QMessageBox::LastButton) {
            uint sb = buttons & mask;
            mask <<= 1;
            if (!sb)
                continue;
            QPushButton *button = msgBox.addButton((QMessageBox::StandardButton)sb);
            // Choose the first accept role as the default
            if (msgBox.defaultButton())
                continue;
            if ((defaultButton == QMessageBox::NoButton && buttonBox->buttonRole((QAbstractButton*)button) == QDialogButtonBox::AcceptRole)
                || (defaultButton != QMessageBox::NoButton && sb == uint(defaultButton)))
                msgBox.setDefaultButton(button);
        }
        if (msgBox.exec() == -1)
            return QMessageBox::Cancel;
        return msgBox.standardButton(msgBox.clickedButton());
    }
    
    CustomMessageBox::CustomMessageBox(QWidget *parent) : QMessageBox(parent)
    {
    
    }
    
    CustomMessageBox::CustomMessageBox(QMessageBox::Icon icon, const QString &title, const QString &text, QMessageBox::StandardButtons buttons, QWidget *parent, Qt::WindowFlags flags)
     : QMessageBox(icon, title, text, buttons, parent, flags)
    {
    
    }
    
    void CustomMessageBox::keyPressEvent(QKeyEvent *e)
    {
        QMessageBox::keyPressEvent(e);
    
        if (e == QKeySequence::Copy) {
            QString separator = QString::fromLatin1("---------------------------\n");
            QString tempText = QApplication::clipboard()->text();
            tempText.append("Your custom text.\n" + separator);
            QApplication::clipboard()->setText(tempText);
        }
    
    }
    
    QMessageBox::StandardButton CustomMessageBox::information(QWidget *parent, const QString &title,
                                   const QString& text, StandardButtons buttons,
                                   StandardButton defaultButton)
    {
        return showNewMessageBox(parent, Information, title, text, buttons,
                                 defaultButton);
    }
    

    Usage:

    void MainWindow::showCustomMessage()
    {
        CustomMessageBox::information(this, "New message", "A lot of text", 0);
    }
    

    Also You might need to override question(), warning(), critical() and some other functions.