-1

I'm using QT creator for creating the Ui form. I've a base form which contains 5 buttons (testListForm). I'm inheriting this base class in my derived class (DisplayTestResultsForm) via TestStatusForm. when i click on the button in the derived class, the function on_pushbutton_1_clicked() getting called thrice. below is the code snippet

class TestListForm :  public TestBaseForm
{
    Q_OBJECT

private slots:
    virtual void on_pushButton_1_clicked();
    virtual void on_pushButton_2_clicked();
    virtual void on_pushButton_3_clicked();
    virtual void on_pushButton_4_clicked();
    virtual void on_pushButton_5_clicked();
}

class TestStatusForm : public TestListForm
{
    Q_OBJECT
     ....
};

class DisplayTestResultsForm : public TestStatusForm
{
    Q_OBJECT

private slots:
    void on_pushButton_1_clicked();
    void on_pushButton_2_clicked();
    void on_pushButton_3_clicked();
    void on_pushButton_4_clicked();
    void on_pushButton_5_clicked();
}

When i call on_pushButton_1_clicked in DisplayTestResultsForm, i'm getting this function getting called thrice. I'm not making any explicit connect call as Ui will take care of this using ConnectSlotByName. Can anyone suggest what could be the problem?

Thanks in advance.

ixSci
  • 13,100
  • 5
  • 45
  • 79

1 Answers1

0

There are two mistakes:

  1. Private slots are local. There's no point in making them virtual, as no derived class sees them. You must make the slots protected.

  2. When you have virtual slots, you must only declare them to moc once. The slots macro is empty and only has meaning to the moc tool. The most base class that declares the slots should have them declared as slots. All of the derived classes must not declare them as slots, but merely as Q_DECL_OVERRIDE reimplementations.

Thus:

class TestListForm :  public TestBaseForm
{
    Q_OBJECT
protected slots: // protected, not private
    virtual void on_pushButton_1_clicked();
    virtual void on_pushButton_2_clicked();
    virtual void on_pushButton_3_clicked();
    virtual void on_pushButton_4_clicked();
    virtual void on_pushButton_5_clicked();
}

class TestStatusForm : public TestListForm
{
    Q_OBJECT
protected: // protected, overriden, no slots macro
    void on_pushButton_1_clicked() Q_DECL_OVERRIDE;
    void on_pushButton_2_clicked() Q_DECL_OVERRIDE;
    void on_pushButton_3_clicked() Q_DECL_OVERRIDE;
    void on_pushButton_4_clicked() Q_DECL_OVERRIDE;
    void on_pushButton_5_clicked() Q_DECL_OVERRIDE;
}
Kuba hasn't forgotten Monica
  • 95,931
  • 16
  • 151
  • 313
  • Hi kuba, Thanks for your suggestion. Yes, virtual slots shouldn't be private. my mistake. i've incorporated your suggestions and now still i'm getting this function called twice. In the moc file i could able to see it only once in the base class as below moc_testlistform.cpp:40: "TestListForm\0on_pushButton_1_clicked\0" moc_testlistform.cpp:82: case 0: _t->on_pushButton_1_clicked(); break; – user3744269 Aug 19 '15 at 11:56
  • @user3744269 I think you fell prey to not providing enough code, because with the changes outlined above the code is perfectly fine **and works OK**. I think I know what you're doing. The `Ui::setupUi` method sets up the connections for you by calling `QMetaObject::connectSlotsByName`. If you call `Ui:setupUi` in one of the base classes, and then a different one in a derived class, you'll get this behavior. Is that the case? If so, let this be a reminder that by not providing a stand alone test case, you're shooting yourself in the foot and wasting everyone's time - yours too. – Kuba hasn't forgotten Monica Aug 19 '15 at 12:32
  • Thanks much for showing me the pointer. You are right. setupUi was getting called in the derived class as well. After removing setupUi in the derived class it worked as expected. Qt is very much new to me. these issues will be new learnings. If i had knew this, i shouldn't have made this mistake. thanks again for solving my issue. – user3744269 Aug 19 '15 at 15:23