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

the slot function is somewhy called 2 times in the signal-slot connection, although should be called only 1 time



  • I have 2 Qt Designer Form Class forms:

    Form1 * form1 = new Form1();
    

    and

    Form2 * form2;
    

    form2 is a private field of Form1 class.
    There is a button on the form1 form. When it is clicked, form1 is hidden and form2 is showed:

    form2 = new Form2();
    hide();
    form2->show();
    connect(form2, SIGNAL(RegisterButtonPressed()), this, SLOT(Register()));
    

    There are some QLineEdit fields on the form2. After the text has been inserted, the button RegisterButton is clicked, and this click emits the RegisterButtonPressed() signal of Form2 class.
    As written above, any time the button RegisterButton is clicked, the method (private slot) Register() of Form1 class should be called.
    But in my program it is called twice! A put the prints at the beginning and at the end of Register(), and see that it is called 2 times. Why? May it be a bug of Qt or my fault? It is the code generated by moc and I don't know how to debug it.


  • Lifetime Qt Champion

    Hi
    Your issue is due to both manual connect and auto connect.

    you have
    connect(ui->RegisterButton, SIGNAL(clicked()), this, SLOT(on_RegisterButton_clicked()));

    but the slot name makes the auto connect also connect it
    on_RegisterButton_clicked matches RegisterButton
    so in setupUI
    it calls
    QMetaObject::connectSlotsByName(RegistrationForm);

    which then make a connection too and hence you get it called twice.

    so either rename slot to avoid auto connect (recommended) or delete the connect statement
    and use the auto-connect.



  • @And92
    Do you delete the form2 = new Form2() instance created above, or disconnect that connect, when you're done with it? Depending on your code, if it;s not exactly like that, if you execute that connect() more than once you will end up with the signal connected multiple times to the slot. Is that something like what is happening? Does Register() slot get called as many times as this code gets executed, e.g. 3 times if you click the button Form1 button 3 times? Or does it only ever get called twice, regardless? I'd look for multiple connections to the slot. It won't be a bug of Qt :)



  • I push on the RegisterButton once, but Register() is called twice. Every time I push the button 1 time, Register() is executed 2 times. This is my problem.
    And i do not do disconnect(), only connect(). Is it an error, should I always do not only connect, but also disconnect()?



  • I think you should post more code. It's hard to tell where is the problem according to current content.
    And it is definitely not a bug of Qt.
    Also, if the RegisterButton is a QPushButton or QToolButton, it's better to not connect to pressed(), but connect to clicked().



  • @And92 said in the slot function is somewhy called 2 times in the signal-slot connection, although should be called only 1 time:

    connect(form2, SIGNAL(RegisterButtonPressed()), this, SLOT(Register()));

    In addition to the above suggestions, please try using the new syntax for signals & slots.



  • @And92 said in the slot function is somewhy called 2 times in the signal-slot connection, although should be called only 1 time:

    There is a button on the form1 form. When it is clicked, form1 is hidden and form2 is showed:

    form2 = new Form2();
    hide();
    form2->show();
    connect(form2, SIGNAL(RegisterButtonPressed()), this, SLOT(Register()));
    

    Take a step back from why the slot is called twice for a moment, while you sort this out first. From what you write, this piece of code is executed each time you click a button on form1, right? So this creates a new instance of a Form2, which you store in form2 variable, and shows it. How/when does this Form2 get removed/deleted/closed? If you do nothing, you will be creating multiple Form2s shown on the screen each time this gets called? If you just let the user close Form2, what do you do about delete-ing the new Form2() you created, and setting form2 = nullptr?



  • I posted the source code here: https://github.com/AndStorm/QtQuestion.git .
    It may be cloned, built and launched. It is not very small, that is why decided not to post it here, because on the forum page it will take a lot of space to paste it.
    The code lines

    form2 = new Form2();
    hide();
    form2->show();
    connect(form2, SIGNAL(RegisterButtonPressed()), this, SLOT(Register()));
    

    are in mainwindow.cpp in the lines 73-76. Form2 (registrationForm) is deleted on the line 32 of mainwindow.cpp. In the code Form1 stands for MainWindow class and Form2 stands for RegistrationForm class.


  • Lifetime Qt Champion

    Hi
    Your issue is due to both manual connect and auto connect.

    you have
    connect(ui->RegisterButton, SIGNAL(clicked()), this, SLOT(on_RegisterButton_clicked()));

    but the slot name makes the auto connect also connect it
    on_RegisterButton_clicked matches RegisterButton
    so in setupUI
    it calls
    QMetaObject::connectSlotsByName(RegistrationForm);

    which then make a connection too and hence you get it called twice.

    so either rename slot to avoid auto connect (recommended) or delete the connect statement
    and use the auto-connect.



  • Thanks, Sir. Deleted connect(ui->RegisterButton, SIGNAL(clicked()), this, SLOT(on_RegisterButton_clicked())); and the Register() is only called once.
    And if to rename on_RegisterButton_clicked() slot, Register is also called only once.
    So, as far as i understand, auto connect is the following: if there is a button with the name RegisterButton on the RegistrationForm, the method QMetaObject::connectSlotsByName(RegistrationForm); starts seeking for on_RegisterButton_clicked() slot. If it finds it, it makes connect(ui->RegisterButton, SIGNAL(clicked()), this, SLOT(on_RegisterButton_clicked()));, without this line written straight ih the code. Is it so?


  • Lifetime Qt Champion

    @And92

    yes the auto connect looks at widget name. lets say Button
    and if it can find a slot named
    on_widgetName_SignalName then it connects it.
    This is often created using right-click on widget and "Goto Slot"

    Whyle handy, its also very fragile so its recommended to manual connect and not name the slots
    on_xxx.



  • Thanks, Sir. I'm new to Qt. I strongly want to learn how to create GUI with Qt.
    What book to start with could You recommend me?
    Jasmin Blanchette "C++ GUI Programming with Qt 4" or anything else?
    I haven't found it in PDF in good quality on the Internet yet.


Log in to reply