Signal And Slots



  • Hi,

    I am trying to connect a combobox with a Qtreewidget.
    I would like to answer if i could create my own slot (function) and connect it with the signal..

    the code is this :
    @
    connect(kliniki,SIGNAL (activated (QString) ),tree,SLOT (fill (QString)));
    @
    i would like to take the user choice from the combo kliniki through the slot fill,
    but somewhere i always do something wrong!

    I need some help.
    thanks

    Edit ("Andre":http://developer.qt.nokia.com/member/438): Code tags. Please use them for formatting code.



  • Sure you can do that. The question is: does tree actually have a slot called fill() that takes a string?

    What error do you get? Do you get any output at runtime concerning signal/slot connections?



  • No the tree doesn't have the slot fill()! i created it and the error was:
    Object::connect: No such slot QTreeWidget::fill(QString) in ....\ARXIKO\qxsrexample.cpp:185.

    what can i do?

    Also what the difference between this
    @connect(kliniki,SIGNAL (activated (QString) ),tree,SLOT (fill (QString)));@
    and this
    @connect(kliniki,SIGNAL (activated (QString) ),this,SLOT (fill (QString))); @

    With the second line i can call the slot fill but i this that there is no connection between the combo and the tree.

    Edit by "Andre":http://developer.qt.nokia.com/member/438: Again, please use code tags for code.



  • The difference between
    @connect(kliniki,SIGNAL (activated (QString) ),tree,SLOT (fill (QString)));@
    and
    @connect(kliniki,SIGNAL (activated (QString) ),this,SLOT (fill (QString)));@
    is:

    With the first statement you tell your program that the slot fill(QString) which is located in the tree-object has to be called if kliniki generates the signal activated(QString). Whereas the second line tells that the slot fill(QString) is located in the actual object where the connect statement is located.

    So if you defined the slot-function within your own implementation of QTreeWidget use the first, otherwise if it is defined in the object that contains the connects the latter.



  • The difference between the two statements is obviously that in the first instance, you connect to whatever object tree is pointing to, while in the second statement you connect to the object you call this code from.

    So, where did you write this fill code for the tree? Could you show the relevant sections of your code?



  • One thing that might make it easier to understand:

    if you have

    @
    connect(obj1, SIGNAL(a()), obj2, SLOT(b()))
    @

    it means obj1 calls (via some magic :-) )
    @
    obj2->b()
    @

    if the signal a() is emitted.



  • Here is my code:

    @
    void QXSRExample::addPersonsToUI()
    {
    QComboBox *kliniki = new QComboBox();

    QMap<QString,QString> clinic2 = persons.takeFirst();
    while(!persons.isEmpty()) 
    {
        QMap<QString,QString> clinic = persons.takeFirst();
        if (clinic2["clinical_department"] != clinic["clinical_department"])
        {
            kliniki->addItem(clinic2["clinical_department"]);
            clinic2=clinic;
        } 
    }
    kliniki->addItem(clinic2["clinical_department"]);
    _layout->addWidget(new QLabel("<h4>KLINIKES</h4>"));
    _layout->addWidget(kliniki);
    connect(kliniki, SIGNAL (activated(QString)), this, SLOT (fill(QString)));
    

    }

    void QXSRExample::fill(QString index)
    {
    _layout->addWidget(new QLabel("<h4>ASTHENEIS</h4>"),0,Qt::AlignCenter);
    _layout->addWidget(new QLabel("<h4>ONOMATEPWNIMO & ETOS GENNHSHS</h4>"));
    QTreeWidget *tree = new QTreeWidget;
    QTreeWidgetItem treeWidgetItem;
    while(!persons2.isEmpty())
    {
    QMap<QString,QString> person = persons2.takeFirst();
    if (index==person["clinical_department"])
    {
    QStringList columns;
    columns << person["surname"] << person["name"] << person["birthdate"];
    tree->setColumnCount(3);
    treeWidgetItem = new QTreeWidgetItem((QTreeWidget
    )0, columns);
    tree->insertTopLevelItem(0, treeWidgetItem);
    }
    }
    _layout->addWidget(tree);
    }
    @

    i take the user choice from the combo "kliniki" through the slot "fill" and in the slot fill i fill the tree widget with data. Is something wrong with my connection? the slot fill doesn't belong to the oblect tree. I created it.
    I think that i did sth wrong in the connection because if the user change his choice from the combo, the tree does not update its data.
    Also, i tried to make the tree object public but thus the tree widget disappears.

    What can i do?

    EDIT: please use only one @-Tag before the complete code and one after...



  • Hi anatz,

    @
    void QXSRExample::addPersonsToUI()
    {
    ...
    connect(kliniki, SIGNAL (activated(QString)), this, SLOT (fill(QString)));
    }
    @

    The signal of a combo box is: activated(const QString&). Have a look at the docs, the signature must be completely the same. So your slot also need to be fill(const QString&).

    For future: please use the @-tags correctly: one in front of the first line of code and one after the last one. no doubles etc...



  • The signatures must be compatible. This implies not necessarily having the same signature than the signal:

    @
    void slotValue(QString s);
    void slotRef(QString &s);
    void slotConstValue(const QString s);
    void slotConstRef(const QString &s);

    // having
    // void QComboBox::activated ( const QString & text ) [signal]

    connect(comboBox, SIGNAL(activated(QString)), this, SLOT(slotValue(QString)));
    connect(comboBox, SIGNAL(activated(QString)), this, SLOT(slotRef(QString&)));
    connect(comboBox, SIGNAL(activated(QString)), this, SLOT(slotConstValue(QString)));
    connect(comboBox, SIGNAL(activated(QString)), this, SLOT(slotConstRef(QString)));
    

    @

    Only the connection to slotRef will fail, the other three are ok. So the code from annatz seems to be ok.

    annatz, did you declare your slot fill() as a slot in your header file?

    @
    protected slots:
    void fill(QString index);
    // better would be
    void fill(const QString &index);
    @

    If you do not declare it as a slot like above the Qt system does not regard the method a such and the connection will eventually fail with the error message in your original post! You have to decide if the slot is public, protected or private, as in regular methods and class members.



  • [quote author="Gerolf" date="1296032815"]Hi anatz,
    The signal of a combo box is: activated(const QString&). Have a look at the docs, the signature must be completely the same. So your slot also need to be fill(const QString&).[/quote]

    Actually, that is not quite true. Qt strips of the const and the & when connecting the two anyway. Also, the slot is allowed to have less parameters than the signal. These will be disgarded.

    Then, on the code:
    What I don't understand in the code is the construction of lots of new widgets when a choice in a combobox is made. Why do you do that? Why don't you just set values on widgets you already have? It seems like a huge waste to create new widgets for every different choice you make in the combo box.



  • Now i understand how signal and slots work.
    And Andre you are right i didn't want to create new widgets and i haven't noticed.

    I am new in qt. Actually, i am trying to do my project to graduate from university.

    Thank you all!


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.