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

Cannot call member function 'void QPlainTextEdit::paste()' without object ^



  • Hi to all,

    1- If possible, please, tell me if I've gone quite right up to this point for the (uncompleted) project below?

    PlainTextEdit.h:

    #ifndef PLAINTEXTEDIT_H
    #define PLAINTEXTEDIT_H
    
    #include <QDialog>
    #include <QAbstractButton>
    
    class QPlainTextEdit;
    class QDialogButtonBox;
    
    class PlainTextEdit : public QDialog
    {
        Q_OBJECT
    
    public:
        PlainTextEdit(QWidget *parent = nullptr);
    
    protected:
        void closeEvent(QCloseEvent *) override;
    
    private slots:
        void save();
        void load();
        void btnBoxClicked(QAbstractButton*);
        void plTxtChanged();
    
    private:
        QPlainTextEdit* pTxtEdit = nullptr;
        QDialogButtonBox* dbtnBox = nullptr;
    
        QPushButton* btnCopy = nullptr;
        QPushButton* btnCut = nullptr;
        QPushButton* btnPaste = nullptr;
        QPushButton* btnUndo = nullptr;
        QPushButton* btnRedo = nullptr;
    
        bool m_saved;
    };
    #endif // PLAINTEXTEDIT_H
    

    PlainTextEdit.cpp:

    #include "plaintextedit.h"
    #include <QPlainTextEdit>
    #include <QDialogButtonBox>
    #include <QPushButton>
    #include <QVBoxLayout>
    #include <QFile>
    #include <QTextStream>
    #include <QMessageBox>
    
    PlainTextEdit::PlainTextEdit(QWidget *parent)
        : QDialog(parent)
    {
        Qt::WindowFlags flags = 0;
        flags |= Qt::WindowMinMaxButtonsHint;
        flags |= Qt::WindowContextHelpButtonHint;
        flags |= Qt::WindowCloseButtonHint;
        setWindowFlags(flags);
    
    
        pTxtEdit = new QPlainTextEdit;
        dbtnBox = new QDialogButtonBox(QDialogButtonBox::Save |
                                       QDialogButtonBox::Open);
        btnCopy = new QPushButton(tr("Copy"));
        btnCut = new QPushButton(tr("Cut"));
        btnPaste = new QPushButton(tr("Paste"));
        btnUndo = new QPushButton(tr("Undo"));
        btnRedo = new QPushButton(tr("Redo"));
    
        dbtnBox->addButton(btnCopy, QDialogButtonBox::AcceptRole);
        dbtnBox->addButton(btnCut, QDialogButtonBox::AcceptRole);
        dbtnBox->addButton(btnPaste, QDialogButtonBox::AcceptRole);
        dbtnBox->addButton(btnUndo, QDialogButtonBox::AcceptRole);
        dbtnBox->addButton(btnRedo, QDialogButtonBox::AcceptRole);
    
        QVBoxLayout* layout = new QVBoxLayout;
        layout->addWidget(pTxtEdit);
        layout->addWidget(dbtnBox);
    
        setLayout(layout);
    
        connect(dbtnBox, &QDialogButtonBox::clicked, this, &PlainTextEdit::btnBoxClicked);
        connect(pTxtEdit, &QPlainTextEdit::textChanged, this, &PlainTextEdit::plTxtChanged);
    }
    
    void PlainTextEdit::closeEvent(QCloseEvent* event)
    {
    
    }
    
    void PlainTextEdit::save()
    {
    
    }
    
    void PlainTextEdit::load()
    {
    
    }
    
    void PlainTextEdit::btnBoxClicked(QAbstractButton* button)
    {
        if(button->text().contains("Save"))
            save();
        else if(button->text().contains("Open"))
            load();
        else if(button->text().contains("Paste"))
            QPlainTextEdit::paste();
    }
    
    void PlainTextEdit::plTxtChanged()
    {
    
    }
    

    I get an error for else if(button->text().contains("Paste")) QPlainTextEdit::paste(); in the slot void PlainTextEdit::btnBoxClicked(QAbstractButton* button) saying: Cannot call member function 'void QPlainTextEdit::paste()' without object.

    Apparently, we can use our base class's method "paste" which doesn't include any argument shown on the intellisense, as above, but that error appears.
    I want to manage all the buttons inside the DialogButtonBox using that slot.

    2- How to fix that issue, please?



  • @tomy

    class PlainTextEdit : public QDialog
    

    Your class derives from QDialog, for whatever reason.

    Cannot call member function 'void QPlainTextEdit::paste()' without object.

    void PlainTextEdit::btnBoxClicked(QAbstractButton* button)
    {
            QPlainTextEdit::paste();
    }
    

    So what are you intending here??



  • @JonB

    Sorry, I made a mistake. I should have written:

    void PlainTextEdit::btnBoxClicked(QAbstractButton* button)
    {
    pTxtEdit->paste();
    }

    Now it works.

    How about the first question, please?


  • Lifetime Qt Champion

    Hi,

    Are you asking for a code review ?



  • @SGaist

    Yes, and if you want to do the favour, please take this new version:

    PlainTextEdit.h:

    #ifndef PLAINTEXTEDIT_H
    #define PLAINTEXTEDIT_H
    
    #include <QDialog>
    #include <QAbstractButton>
    
    class QPlainTextEdit;
    class QDialogButtonBox;
    
    class PlainTextEdit : public QDialog
    {
        Q_OBJECT
    
    public:
        PlainTextEdit(QWidget *parent = nullptr);
    
    protected:
        void closeEvent(QCloseEvent *) override;
    
    private slots:
        void save();
        void load();
        void btnBoxClicked(QAbstractButton*);
        void plTxtChanged();
    
    private:
        QPlainTextEdit* pTxtEdit = nullptr;
        QDialogButtonBox* dbtnBox = nullptr;
        bool m_saved;
    };
    #endif // PLAINTEXTEDIT_H
    
    

    PlainTextEdit.cpp:

    #include "plaintextedit.h"
    #include <QPlainTextEdit>
    #include <QDialogButtonBox>
    #include <QPushButton>
    #include <QVBoxLayout>
    #include <QFile>
    #include <QTextStream>
    #include <QMessageBox>
    
    PlainTextEdit::PlainTextEdit(QWidget *parent)
        : QDialog(parent)
    {
        Qt::WindowFlags flags = 0;
        flags |= Qt::WindowMinMaxButtonsHint;
        flags |= Qt::WindowContextHelpButtonHint;
        flags |= Qt::WindowCloseButtonHint;
        setWindowFlags(flags);
    
        pTxtEdit = new QPlainTextEdit;
        dbtnBox = new QDialogButtonBox(QDialogButtonBox::Save |
                                       QDialogButtonBox::Open);
        dbtnBox->addButton(tr("Copy"), QDialogButtonBox::ActionRole);
        dbtnBox->addButton(tr("Cut"), QDialogButtonBox::ActionRole);
        dbtnBox->addButton(tr("Paste"), QDialogButtonBox::ActionRole);
        dbtnBox->addButton(tr("Undo"), QDialogButtonBox::ActionRole);
        dbtnBox->addButton(tr("Redo"), QDialogButtonBox::ActionRole);
    
        QVBoxLayout* layout = new QVBoxLayout;
        layout->addWidget(pTxtEdit);
        layout->addWidget(dbtnBox);
    
        setLayout(layout);
    
        connect(dbtnBox, &QDialogButtonBox::clicked, this, &PlainTextEdit::btnBoxClicked);
        connect(pTxtEdit, &QPlainTextEdit::textChanged, this, &PlainTextEdit::plTxtChanged);
    
        load();
    }
    
    void PlainTextEdit::closeEvent(QCloseEvent* event)
    {
      event->accept();
    }
    
    void PlainTextEdit::save()
    {
        QFile file("text.txt");
        if(!file.open(QIODevice::WriteOnly))
        {
            QMessageBox::critical(this, "Error!", file.errorString());
            return;
        }
    
        QTextStream stream(&file);
        stream << pTxtEdit->toPlainText();
    
        file.close();
        QMessageBox::information(this, "Saved!", "Filr is saved!");
        m_saved = true;
    }
    
    void PlainTextEdit::load()
    {
        pTxtEdit->clear();
    
       QFile file("text.txt");
       if(!file.open(QIODevice::ReadOnly) || !file.exists())
       {
           QMessageBox::critical(this, "Error!", file.errorString());
           return;
       }
    
       QTextStream stream(&file);
       pTxtEdit->setPlainText(stream.readAll());
       file.close();
    }
    
    void PlainTextEdit::btnBoxClicked(QAbstractButton* button)
    {
        if(button->text().contains("Save"))
            save();
        else if(button->text().contains("Open"))
            load();
        else if(button->text().contains("Copy"))
            pTxtEdit->copy();
        else if(button->text().contains("Cut"))
            pTxtEdit->cut();
        else if(button->text().contains("Paste"))
            pTxtEdit->paste();
        else if(button->text().contains("Undo"))
            pTxtEdit->undo();
        else if(button->text().contains("Redo"))
            pTxtEdit->redo();
    }
    
    void PlainTextEdit::plTxtChanged()
    {
      m_saved = false;
    }
    

  • Lifetime Qt Champion

    PlainTextEdit is a misleading name, it suggests it's a subclass of QPlainTextEdit.

    You have inconsistent naming styles for your class member variable.

    There's no need for that button slot, you can directly connect them directly to the corresponding slot at creation time.

    If you keep them, you should ensure that you string comparison can support translations.

    Why did you reimplement closeEvent since you don't do anything specific in it ?

    Your custom slots should rather follow the onXxxxChanged pattern. This makes the method intention clear.



  • @SGaist

    Thank you for your remarks.
    I accepts all except the third one:

    There's no need for that button slot, you can directly connect them directly to the corresponding slot at creation time.

    I declared that button slot mostly to address the save and load functions.

    And please, how to "connect them directly to the corresponding slot at creation time"?


  • Lifetime Qt Champion

    In the constructor, the addButton method returns the button you have created so you can do all the appropriate connections at that time.



  • @SGaist

    So for that I need to define at least 5 buttons and 5 + 2 connections. Is it not messier than one single slot taking care of all these?


  • Lifetime Qt Champion

    Personally I don't but that's my taste. Don't forget that your current slot will only work as long your application is not translated.

    Another thing to take into account is that you have to ensure at two different places that your strings are correct.



  • @SGaist
    are your talking about tr("")? If so, then I said it's right in the above post when I said I accept all your suggestions. I thought we talked about the slot at the end, and not its string arguments. Hence, I conclude that the slot is fine and the other suggestions must be kept in mind for the next apps. thanks. :)


Log in to reply