Search code examples
c++c++11qt5qbuttongroupqabstractbutton

problem with SIGNAL SLOT new notation for QAbstractButton


I am writing a small utility composed by :

1) 4 QToolBar

2) 1 QToolBox

3) 1 QMenu

4) 1 QGraphicsView

I have some buttons on the QToolBox, each button represents a grid with different spacing. Everytime a user clicks a button on the QToolBox the spacing on the QGraphicsScene` changes.

I use daily the new notation and never had any problems with it until I had to use an "abstract" entity such as the QAbstractButton approach.

the problem I have is that I don't seem to properly set the connection signal/slot of the QAbstractButton:

mainwindow.h

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void backgroundButtonClicked(QAbstractButton *button);

private:
    void createToolBox();
    QButtonGroup *buttonGroup;
    QButtonGroup *backgroundButtonGroup;

mainwindow.cpp

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    createToolBox();

    scene = new DiagramScene(itemMenu,this);
    QHBoxLayout *layout = new QHBoxLayout;
    layout->addWidget(toolBox);
    view = new QGraphicsView(scene);
    QWidget *widget = new QWidget;
    widget->setLayout(layout);
    setCentralWidget(widget);
}

void MainWindow::backgroundButtonClicked(QAbstractButton *button)
{
    QList<QAbstractButton*> buttons = backgroundButtonGroup->buttons();
    foreach (QAbstractButton *myButton, buttons) {
        if(myButton != button)
            button->setChecked(false);
    }
    QString text = button->text();
    if(text == tr("Blue Grid"))
        scene->setBackgroundBrush(QPixmap(":/images/background1.png"));
    else if(text == tr("White Grid"))
        scene->setBackgroundBrush(QPixmap(":/images/background2.png"));
    else if(text == tr("Gray Grid"))
        scene->setBackgroundBrush(QPixmap(":/images/background3.png"));
    else
        scene->setBackgroundBrush(QPixmap(":/images/background4.png"));

    scene->update();
    view->update();
}


void MainWindow::createToolBox()
{
    buttonGroup = new QButtonGroup(this);
    buttonGroup->setExclusive(false);

    QGridLayout *layout = new QGridLayout;
    layout->addWidget(createCellWidget(tr("Conditional"), DiagramItem::Conditional), 0, 0);
    layout->addWidget(createCellWidget(tr("Process"), DiagramItem::Step), 0, 1);
    layout->addWidget(createCellWidget(tr("Input/Output"), DiagramItem::Io), 1, 0);

    QToolButton *textButton = new QToolButton;
    textButton->setCheckable(true);
    buttonGroup->addButton(textButton, InsertTextButton);
    textButton->setIcon(QIcon(QPixmap(":/images/textpointer.png")));
    textButton->setIconSize(QSize(50, 50));
    
    QWidget *itemWidget = new QWidget;
    itemWidget->setLayout(layout);

    backgroundButtonGroup = new QButtonGroup(this);

    // This is my first attempt but it does not work:

    QObject::connect(backgroundButtonGroup, &QAbstractButton::clicked, this, &QAbstractButton::backgroundButtonClicked());


}

Different options I tried are:

1) via static_cast<> trying to cast it into the QAbstractButton as shown below:

QObject::connect(static_cast<QAbstractButton*>(backgroundButtonGroup), this, static_cast<QAbstractButton>(backgroundButtonClicked(void)));

2) Also I tried the following according to official documentation but that also didn't work:

QObject::connect(backgroundButtonGroup, &QAbstractButton::clicked, this, &QAbstractButton::backgroundButtonClicked);

Adding to that I was digressing towards the following structure below (heading to Q_INVOKE) but I am afraid I was over complicating the issue, but just wanted to include the additional solution I was trying to explore:

const bool connected = connect(sender, &Sender::aSignal, 
                               receiver, &Receiver::aSlot);
Q_ASSERT(connected);
Q_UNUSED(connected);

Thanks for pointing to the right direction for solving this issue.


Solution

  • You have the following errors:

    • QButtonGroup does not have the clicked signal but buttonClicked.
    • You must not use ().

    The syntax in general is: obj, & Class_of_obj, in your case backgroundButtonGroup is QButtonGroup and this is MainWindow so preliminarily the syntax is:

    QObject::connect(backgroundButtonGroup, &QButtonGroup::buttonClicked, this, &MainWindow::backgroundButtonClicked);
    
    • But buttonClicked is overload then you must use QOverload to indicate the signature.

    Considering the above, the solution is:

    QObject::connect(backgroundButtonGroup, QOverload<QAbstractButton *>::of(&QButtonGroup::buttonClicked), this, &MainWindow::backgroundButtonClicked);
    

    I recommend you check: