-2

I am writing a programm, that creates a QLineEdit that only accepts digits and should, when it rejects an input that is not a digit, turn the background to some abitrary color. If the input is accpeted it will turn the background white again. Now I need to connect the inputRejected and textEdited events of the QLineEdit to randomcolor() and white() respectively, but the connect is making me trouble and i do not know how to fix it.

This is the first time I'm working with the connect and i slugged through many forums alreay trying out the different Syntax i found there.

#include <QtWidgets>

class OnlyNumbers : QLineEdit {
   public:
        static int spawn(int argc, char *argv[]){
            QApplication app(argc, argv);
            OnlyNumbers P;
            return app.exec();
        }
        OnlyNumbers() : QLineEdit() {
            this->setValidator(new QIntValidator());
            QObject::connect(this, SIGNAL(inputRejected()), this, SLOT(randomcolor()));
            QObject::connect(this, SIGNAL(&QLineEdit::textEdited(const QString)), this, SLOT(&OnlyNumbers::white()));
            QRegExp rx("[0-9]*");            QValidator *validator = new QRegExpValidator(rx, this);
            this->setValidator(validator);
            this->show();

        }
    public slots:
        void randomcolor(){
            this->setStyleSheet("QLineEdit { background: rgb(std::rand()%256, rand()%256, rand()%256); selection-background-color: rgb(rand()%256, rand()%256, rand()%256); }");
        }
        void white(){
            this->setStyleSheet("QLineEdit { background: rgb(255, 255, 255); selection-background-color: rgb(233, 99, 0); }");
        }
};

int main(int argc, char *argv[])
{
    return OnlyNumbers::spawn(argc, argv);
}

QObject::connect: No such slot QLineEdit::randomcolor()

QObject::connect: No such signal QLineEdit::&QLineEdit::textEdited(const QString)

These are the errors i get, and i don't know what to do with them, because for em the two are existant. Sadly I cannot describe my problem better, because i don't know more.

SOLVED: The Problem was, that i didn't seperate calls definition and declaration in onlynumbers.h and onlynumbers.cpp. Also i cannot put std::rand()%256 in the string i need to split the string and concatonate it with all the numbers converted to a qstring. :D Thanks for the help. You gave me the motivation to keep googeling.

Deedit
  • 69
  • 1
  • 6
  • 1
    Replace `QObject::connect(this, SIGNAL(&QLineEdit::textEdited(const QString)), this, SLOT(&OnlyNumbers::white()));` with `QObject::connect(this, SIGNAL(textEdited(const QString)), this, SLOT(white()));` you seem to be mixing the Qt4 annd Qt5 connect methods. – drescherjm Jun 30 '19 at 14:03
  • 1
    You really shouldn't use the old string based signal/slot connection syntax with the `SIGNAL` and `SLOT` macros any more. Better to use the new - [compile time checked, pointer to member function based syntax](https://doc.qt.io/qt-5/signalsandslots-syntaxes.html#). It's both safer and faster. – Jesper Juhl Jun 30 '19 at 14:03
  • 2
    You could also use the Qt5 syntax `QObject::connect(this, &QLineEdit::textEdited, this,&OnlyNumbers::white);` – drescherjm Jun 30 '19 at 14:11

1 Answers1

5

You forgot Q_OBJECT for your class. For example:

class OnlyNumbers : QLineEdit {
    Q_OBJECT    
    ...

See the documentation on QObject:

Notice that the Q_OBJECT macro is mandatory for any object that implements signals, slots or properties.

Without the macro the meta compiler simply will not generate the information needed for the slots/signals declared in your class.

Also, after Q_OBJECT has been added you should rerun qmake on your project since qmake actually generates the calls to moc in the makefile. This is explained by the documentation of the Meta-Object Compiler (moc):

Whenever qmake is run, it parses the project's header files and generates make rules to invoke moc for those files that contain a Q_OBJECT macro.

Also as mentioned in the comments - the SIGNAL/SLOT macros are the old string based implementation, and there are many benefits to switch to the new compile time checked connect - see New Signal Slot Syntax and Differences between String-Based and Functor-Based Connections.

Rudolfs Bundulis
  • 11,636
  • 6
  • 33
  • 71
  • 2
    With the new compile time checked syntax, `Q_OBJECT` is no longer needed for slots. Only for signals. – Jesper Juhl Jun 30 '19 at 14:04
  • After adding Q_OBJECT i am getting undefined reference to `vtable for OnlyNumbers' and collect2.exe:-1: Fehler: error: ld returned 1 exit status. It read this error comes from my compiler, so im giving the code to one of my friends to test, because i don't get what i should do with this error – Deedit Jun 30 '19 at 14:11
  • 1
    That means `moc` was not run after the change. You may have to run `QMake` or regenerate your project depending on how you are building. – drescherjm Jun 30 '19 at 14:13
  • 1
    @JesperJuhl that is a very good point, I'll fix the answer:) But the guy is still using `SIGNAL/SLOT` macros, so it is relevant for him. – Rudolfs Bundulis Jun 30 '19 at 14:22
  • 1
    Yes please add the fix for the signal / slot problem. This answer does not address the main issue with the question. – drescherjm Jun 30 '19 at 14:27
  • @JesperJuhl - I updated the answer but looking at QT docs I could not find a reference to the statement that `Q_OBJECT` is no longer needed for slots. Can you maybe share a link for that? Since I was not aware of that, but I'd actually like to read and understand why/how the new functor based syntax lifts the meta info only from slots. Thanks:) – Rudolfs Bundulis Jun 30 '19 at 15:41
  • @drescherjm well, op's main problem was missing `Q_OBJECT`. I expanded the answer that he needs to rerun qmake, but what did you mean with "answer does not address the main issue" ? – Rudolfs Bundulis Jun 30 '19 at 15:42
  • @RudolfsBundulis It falls out, quite naturally, of the fact that you are now connecting to regular member functions, functors, lambdas. Of course there is no need for the `Q_OBJECT` macro to do that. It's just plain C++. This may be helpful: https://wiki.qt.io/New_Signal_Slot_Syntax – Jesper Juhl Jun 30 '19 at 15:46
  • @JesperJuhl @drescherjm @RudolfsBundulis Q_OBJECT was definitely missing, when using ```QObject::connect(this, SIGNAL(inputRejected()), this, SLOT(randomcolor())); QObject::connect(this, SIGNAL(textEdited(const QString)), this, SLOT(white()));```. The main thing though after that was to seperate the class into its header and definiton. Thanks a lot for your help! – Deedit Jun 30 '19 at 22:00