为什么在运行时没有调用我的插槽?

时间:2014-05-30 00:59:51

标签: c++ qt

我对QT很新,并尝试在运行时添加一个按钮(在点击时发出信号)。我为添加本身添加了一个插槽,但它没有用。出于测试目的,我在代码中放置printf("Hello World");以查看调用方法的时间。

奇怪的是,我得到了我的" Hello World"只有当我关闭程序时......出于测试目的,我在我的主程中调用了add-Method。如果我点击按钮没有任何反应。当我从主要部分移除它时,我甚至不再接受它......

也许有人可以告诉我我做错了什么?

ButtonCreator.h

QT_BEGIN_NAMESPACE
class QAction;
class QGroupBox;
class QPushButton;
class QVBoxLayout;
class QGridLayout;

QT_END_NAMESPACE

class ButtonCreator : public QWidget {
    Q_OBJECT

public:
    ButtonCreator();

private:
    void createGridGroupBox();
    unsigned int buttoncount; //Number of current buttons


    QVBoxLayout *mainLayout; //Main Window
    QGroupBox *gridGroupBox; //Window with Buttons
    QGridLayout *layout; //Button-Layout

    QPushButton* getAddButton();
public slots:
    int addButton(QIcon *icon = 0); //Add Button
};

ButtonCreator.cpp

#include <QtGui>
#include "ButtonCreator.h"


ButtonCreator::ButtonCreator() {
    createGridGroupBox(); //Create Window

    mainLayout = new QVBoxLayout;
    mainLayout->addWidget(gridGroupBox);
    mainLayout->addWidget(getAddButton());
    setLayout(mainLayout);

}

void ButtonCreator::createGridGroupBox() {
    gridGroupBox = new QGroupBox();
    layout = new QGridLayout;    
    gridGroupBox->setLayout(layout);
}

int ButtonCreator::addButton(QIcon *icon) {
    printf("Hello World");
    QPushButton *button = new QPushButton();    

if (icon != 0) {
    button->setIcon(*icon);
}
    layout->addWidget(button, 0, buttoncount);    
    buttoncount++;

    button->show();            //Adding that didn't change anything
    gridGroupBox->update();    //Adding that didn't change anything
    layout->update();          //Adding that didn't change anything


    return buttoncount;
}


QPushButton* ButtonCreator::getAddButton() {
    QPushButton *addbutton = new QPushButton();

    QPixmap pixmap(100, 100);
    pixmap.fill(QColor("blue"));
    QIcon icon = QIcon(pixmap);

    connect(addbutton, SIGNAL(clicked()), this, SLOT(addButton(&icon)));
    return addbutton;
}

我想添加的信号相关我有点困惑。很容易找到如何定义插槽但与信号有关,我甚至不确定我是否理解其中的差异。

例如,如果按下按钮,它会将绝对按钮数作为信号发送。这样做是否正确:

ButtonCreator.h

class ButtonCreator : public QWidget {
..
signals:
void getAbsButtons(int anyPara); 
..
}

并添加:

connect(newButton, SIGNAL(clicked()), this, SLOT(getAbsButtons(para)));

http://www.qtcentre.org/threads/19493-creating-custom-signal他们也有类似的讨论。让我感到困惑的是,我正像一个插槽一样踩着信号......

1 个答案:

答案 0 :(得分:2)

因为您的SLOT addButton(&icon)在运行时永远不会被执行。

虽然可以将SLOT视为常规C ++函数,但只有在将其作为函数调用时才能检索它的返回值。此外,SIGNAL&amp; SLOT机制,最终moc将根据其功能签名替换与C ++代码的连接。最好记住,SLOT的参数号应该小于SIGNAL的参数号。

例如,这些连接将起作用:

connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed(Qbject*)));
connect(sender, SIGNAL(destroyed(QObject*)), this, SLOT(objectDestroyed()));
connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed()));

但是这个不会:

connect(sender, SIGNAL(destroyed()), this, SLOT(objectDestroyed(QObject*)));

因为此SLOT SLOT(objectDestroyed(QObject*)将期望信号不会发送QObject。如果您使用Qt创建者,将报告此连接的运行时错误。


关于你的第二个问题,如果你想发送点击信号并附带一些论点,至少有3种方法可以实现你想要的,你在OP connect(newButton, SIGNAL(clicked()), this, SLOT(getAbsButtons(para)));中提到的不会因为:首先,这是一个失败的连接。其次,clicked() SIGNAL不发送任何信息,它只是作为触发器。如果您希望在点击它时从clicked(int)发送QPushButton之类的SIGNAL,您可以:

  1. QPushButton进行子类化并重新实现鼠标单击事件以使其成为EMIT clicked(int)

  2. 将SIGNAL clicked()连接到SLOT onClicked()。在onCLicked()内,EMIT另一个SIGNAL toFinalDestination(int)到SLOT FinalDestination(int)

  3. 使用QSignalMapperenter image description here

  4. 有关QSignalMapper的详情,请查看this linkthe document


    <强> [编辑]:

    SLOT函数可以作为常规C ++函数(编译时)或SLOT(运行时)调用。函数connect()用于在运行时通过SIGNAL访问SLOT功能,因此您只需要将类型的参数传递给connect(),并且将确定发送的变量在运行时(发出信号)。从你原来的帖子中,我认为你错误地将你的插槽视为connect()中的正常功能,它可能是你的盲点。