Unsolved 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 slotvoid 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?
-
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??
-
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?
-
Hi,
Are you asking for a code review ?
-
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; }
-
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.
-
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"?
-
In the constructor, the addButton method returns the button you have created so you can do all the appropriate connections at that time.
-
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?
-
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 abouttr("")
? 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. :)