QT - connecting wrong button from member QWidget

113 views Asked by At

I have a main window which opens a new window and connects a button from the new window to a "close" function. The problem arises when that new window has more than one button; it will always connect the last created button instead of the explicited one. Here is a sample working code:

"main.cpp"

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

"mainwindow.h"

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include "screen_char_info.h"
#include <QMainWindow>

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    QPushButton *button_show_char_info;
    Screen_Char_Info *screen_char_info;

    QWidget *mainwidget;
    QVBoxLayout *layout_main;

    MainWindow(QWidget *parent = 0) : QMainWindow(parent) {
        button_show_char_info = new QPushButton("Character info", this);
        layout_main = new QVBoxLayout();
        mainwidget = new QWidget(this);


        screen_char_info = NULL;

        QObject::connect (button_show_char_info, &QPushButton::clicked, [this]{
            if (screen_char_info == NULL) {
                screen_char_info = new Screen_Char_Info();
                screen_char_info->show();
                QObject::connect (screen_char_info->button_return, &QPushButton::clicked, [=] {
                    screen_char_info->close();
                    screen_char_info = NULL;
                });
            }
        });



        layout_main->addWidget(button_show_char_info);
        mainwidget->setLayout(layout_main);
        setCentralWidget(mainwidget);
    }

    ~MainWindow()
    {

    }

};

#endif // MAINWINDOW_H

"screen_char_info.h"

#ifndef SCREEN_CHAR_INFO_H
#define SCREEN_CHAR_INFO_H

#include <QString>
#include <QMenu>
#include <QMenuBar>
#include <QLabel>
#include <QTextEdit>
#include <QPushButton>
#include <QWidget>
#include <QLineEdit>
#include <QGridLayout>

class Screen_Char_Info : public QWidget {
    Q_OBJECT

public:
    QPushButton *buttons_modify_attributes[15];
    QPushButton *button_return;
    QGridLayout *layout;

    Screen_Char_Info () {
        this->setAttribute(Qt::WA_DeleteOnClose);
        this->setWindowTitle("Character Info");
        layout = new QGridLayout(this);

        for (int i = 0; i <= 15; i++) {
            buttons_modify_attributes[i] = new QPushButton((i%2 ? "-" : "+"), this);
            connect(buttons_modify_attributes[i], &QPushButton::clicked, [this] {

            });
            layout->addWidget(buttons_modify_attributes[i], (i / 2), (i % 2), 1, 1);
        }


        layout->addWidget(button_return = new QPushButton("Return", this), 8, 0, 1, 1);


        this->setLayout(layout);
    }

};

#endif // SCREEN_CHAR_INFO_H

However, if i put the line layout->addWidget(button_return... before the for loop, the button that closes the window is the last "-" button, and not the return one.

2

There are 2 answers

0
Noel On BEST ANSWER

Found the bug, I was declaring a button matrix with 15 elements, but iterating over a 16 element loop. The 16th element was the return button, and was overwritten in the loop.

0
Alexander V On

The way you do the connect does not appear to be conventional. Try using traditional Qt way:

connect(pButtonToPress, SIGNAL(clicked()), pObjectToHandle, SLOT(onClicked));

Provided QPushButton* pButtonPress actually pointing to QPushButton and pObjectToHandle to some object (can be 'this' pointer):

class ObjHandler
{
   public slot:
      void onClicked();
};

... should satisfy. SIGNAL and SLOT are macro that work with some help of Qt meta object compiler. That is why having slot: statement is highly critical.