PDA

View Full Version : Signal-slots connection problem.



impeteperry
20th January 2007, 03:58
I am using the Qt-4 designer "ui" front end for controlling all aspects of a complex program I am writing.

Each of the "pushbuttons" in the designer window will have many different actions (and labels) depending on program requirements.

My problem is connecting the "signal" (click) of a button to a "slot" in a "control.cpp" function.

In qt3, i could write a "slot", but am at a loss herep

help would be appreciated.
thanks.

e8johan
20th January 2007, 09:24
Have you read this? http://doc.trolltech.com/4.2/designer-using-a-component.html

wysota
20th January 2007, 10:05
And this as well: http://www.qtcentre.org/forum/faq.php?faq=qt_faq_section#faq_qt_designer_categor y

impeteperry
20th January 2007, 14:58
Thanks
No I haven't on both counts. Will do.

Brandybuck
20th January 2007, 19:45
In qt3, i could write a "slot", but am at a loss here
Designer is no longer a text editor in Qt 4. It's not trying to be an IDE. It's just a form editor. If you want to write code, you will need to use your favorite text editor. Write the code for the slot in your widget class using your text editor. It really isn't that hard.

impeteperry
20th January 2007, 20:49
Hi mysota,
I had actually used the "calculatorform" you suggested as a guide for my program
In the example, Items change from within the designer as a result of a user action on an item.

I have a row of 12 "PushButtons" and a row of 12 labels (F1....F12)
The labels on the buttons change as the program progresses.

In my program the user has to click on a button, press a keyboard function key or enter an accelerator letter to do anything.

So, I need to know in my calculatorform.cpp which button was clicked. (function keys and accelerator letters aren't any problem).

I have looked at other examples and i haven't found this condition addressed.

I know this approach is not standard, but neither is my program.
To better understand what I'm trying to do look at "Qcad" . Instead of Icons, I have push buttons across the bottom of the screen to perform the same type of function.

thanks

Brandybuck
21st January 2007, 00:24
So, I need to know in my calculatorform.cpp which button was clicked. (function keys and accelerator letters aren't any problem).
Sorry, I misunderstood your question in my response. What you are looking for is either QSignalMapper, or using QObject::sender().

But be careful of your design. If you are using function keys, accelerators and buttons to initiate actions, then you might want to use QActions for all of your actions. Just a thought.

impeteperry
21st January 2007, 01:51
thanks for you suggestions, I will look into them.

I have been writting this program over the past year or so in straight Qt4. using hard coding for the user interface. (which remains the same throughout the program.) This coding is large, unwieldy and time consuming to make changes.

So, for the new year I would go back and use "designer" for the front end. (I did the original in Qt-3 designer and then used the "ui_,,," file as a guide for the hard coding)

By the way,I had written a crude "labels" program using the same type of user interface for an elderly friend of mine who was having all kinds of trouble with "Notes" and "MS office" sorting routines etc.
It took her 20 minutes to learn and use my program. No icons, no popup or popdown menus etc.

impeteperry
21st January 2007, 02:13
Yes, QActions could do it. i had used them in a visualBasic program several years ago, but I would prefer to do it in designer, not as a menu bar.

I don't think QSignalMapper or QObject::sender() are designed to do what I want.

I am not sure what your warning obout using, button, function keys and/or accelerator keys concerns.

thanks for the help and suggestions.

impeteperry
21st January 2007, 07:18
I found this in the documentation
void QAbstractButton::click () [slot]

Performs a click.

All the usual signals associated with a click are emitted as appropriate. If the button is checkable, the state of the button is toggled.

This function does nothing if the button is disabled. so went back to my non-detigner program for button click.
connect( pb5, SIGNAL( clicked() ), this, SLOT( slotPb5() ) ); Then went to the implementation
void dlgMain::slotPb5()
{
QStringList temp;
QString k;

if( pb5->text() == "~" ) return;
emit setButtonActionList( 5, "5" );
so why not in designer? In the "Signnl Slot Editor" i have:
" pb5 clicked Pb5 click() "
and in my program I have
#include <QtGui>

#include "pmform.h"

PmForm::PmForm(QWidget *parent)
: QWidget(parent)
{
ui.setupUi(this);

ui.leZone->setText("leZone");
}

void PmForm::Pb5()
{
ui.leZone->setText("This is what I want");
}
it compiles ok, but when I run it and click on the "Pb5" button I get
pete@peteBox:~/Desktop/PM-designer/pm$ ./pm
Segmentation fault
pete@peteBox:~/Desktop/PM-designer/pm$ At least I am getting a connection form inside designer to my "pmform.cpp"
Now, how do I get rid of the segmentation fault?

Thanks, Help would be most appreciatei.

impeteperry
21st January 2007, 07:27
I was wrong in the above post. I did not get the connection, i just exited the designer. There HAS to be a simple asswer somewhere!!!

discouraged.

jpn
21st January 2007, 10:40
How about QButtonGroup? You can either identify each button with an identifier and use signal QButtonGroup::clicked(int id), or alternatively you can use signal QButtonGroup::clicked(QAbstractButton* button) to get pointer to the button which was clicked. The already suggested QSignalMapper and QObject::sender() would have had done basically the same.

impeteperry
21st January 2007, 16:30
Thanks, I'll look at your suggestions before I go back to Qt3 which worked fine.

impeteperry
21st January 2007, 18:50
OK thanks to you all who tried to help me. I appreciate it.
I have solved my problem.

I did not use the "signal/slot editor" in designer.

I added the followi code to my constructor
connect( ui.pb1, SIGNAL(clicked()), this, SLOT(slotPb1()));
connect( ui.pb2, SIGNAL(clicked()), this, SLOT(slotPb2()));
connect( ui.pb3, SIGNAL(clicked()), this, SLOT(slotPb3()));
connect( ui.pb4, SIGNAL(clicked()), this, SLOT(slotPb4()));
connect( ui.pb5, SIGNAL(clicked()), this, SLOT(slotPb5()));
connect( ui.pb6, SIGNAL(clicked()), this, SLOT(slotPb6()));
connect( ui.pb7, SIGNAL(clicked()), this, SLOT(slotPb7()));
connect( ui.pb8, SIGNAL(clicked()), this, SLOT(slotPb8()));
connect( ui.pb9, SIGNAL(clicked()), this, SLOT(slotPb9()));
connect( ui.pb10, SIGNAL(clicked()), this, SLOT(slotPb10()));
connect( ui.pb11, SIGNAL(clicked()), this, SLOT(slotPb11()));
connect( ui.pb12, SIGNAL(clicked()), this, SLOT(slotPb12()));
and the slots
void PmForm::slotPb1()
{
ui.leZone->setText("This is Pb1");
}
void PmForm::slotPb2()
{
ui.leZone->setText("This is Pb2");
}
void PmForm::slotPb3()
{
ui.leZone->setText("This is Pb3");
}
etc.
This does what I want. How simple and obvious!!

jpn
21st January 2007, 19:02
QButtonGroup* grp = new QButtonGroup(this);
grp->addButton(ui.pb1, 1);
grp->addButton(ui.pb2, 2);
...
grp->addButton(ui.pb12, 12);
connect(grp, SIGNAL(buttonClicked(int)), this, SLOT(slotPb(int))

void PmForm::slotPb(int id)
{
ui.leZone->setText(QString("This is Pb%1").arg(id));
}

impeteperry
21st January 2007, 19:21
jpn, I had posted my last post before I opened yours which would have given me the clue I needed. thanks

Brandybuck
21st January 2007, 19:48
connect( ui.pb1, SIGNAL(clicked()), this, SLOT(slotPb1()));
connect( ui.pb2, SIGNAL(clicked()), this, SLOT(slotPb2()));
connect( ui.pb3, SIGNAL(clicked()), this, SLOT(slotPb3()));
connect( ui.pb4, SIGNAL(clicked()), this, SLOT(slotPb4()));
connect( ui.pb5, SIGNAL(clicked()), this, SLOT(slotPb5()));
connect( ui.pb6, SIGNAL(clicked()), this, SLOT(slotPb6()));
connect( ui.pb7, SIGNAL(clicked()), this, SLOT(slotPb7()));
connect( ui.pb8, SIGNAL(clicked()), this, SLOT(slotPb8()));
connect( ui.pb9, SIGNAL(clicked()), this, SLOT(slotPb9()));
connect( ui.pb10, SIGNAL(clicked()), this, SLOT(slotPb10()));
connect( ui.pb11, SIGNAL(clicked()), this, SLOT(slotPb11()));
connect( ui.pb12, SIGNAL(clicked()), this, SLOT(slotPb12()));

Ouch! As jpn says, this is a candidate for QButtonGroup.

When you have many similar controls connecting to many similar slots, it is a clue that come sort of consolidation is needed. One appproach is QSignalMapper, which you can use to map senders to specific slot parameter values. It is good for the general case, but you have a specific case where all senders are buttons. Because of that, QButtonGroup is the simplest choice.

impeteperry
22nd January 2007, 03:39
Ok, as I see it, with a button group, I would need 1 signal slot in which the position of the button is returned and that is what I want.

I shall try it.
Thanks

impeteperry
22nd January 2007, 06:52
I tried the "button box" as you suggested. I didn't spend much time, but the button box insisted on an "OK" and a "Cancel" button which I don't want

I then tried the group box. It took up more vertical height then just have the buttons as I have done.

I am willing to spend more time in programming to save valuable screen space, but it was a worthwhile suggestion. thanks.

jpn
22nd January 2007, 08:23
??

QButtonGroup is nothing visible, it just manages buttons as a group. There is no way to setup a QButtonGroup from the Designer. The above example shows how to use QButtonGroup to avoid separate slots for each of those 12 buttons...

impeteperry
22nd January 2007, 17:49
Thanks jpn
In the earlier version of the program I used the button group so I am familiar with it.

I was able to put the buttons in a "group box" in designer, but it took up more screen height then with individual buttons and the 12 signal-slot are no problem.

Thanks anyway

jpn
22nd January 2007, 17:57
I'm starting to get the feeling that we are not understanding each other. We are talking about different things here.

In Qt3 QButtonGroup is a widget. In Qt4 it's not a widget nor nothing visible. It's just a concept of grouping any set of buttons together as a functionality. The buttons can even have different parents, and it has nothing to do with how the buttons are actually laid out.

The QButtonGroup example of mine was for Qt4. I wasn't talking about layouting or organizing the buttons in a form. I was talking about how to avoid those bunch of slots. It can be done with a single slot as the example was meant to present.

impeteperry
22nd January 2007, 23:00
Maybe we are. I was unable to find "button group" in your post. The only thing besides the text was two ?? in the upper left corner of the screen.

I'm a perverse old f... and not always wise, but you gave me good advise and some good information (can't use button groups in designer)

As an 80 old engineer my main thrust is setting up a standard user interface suitable for a wide range of programs where a new user, who knows his/her field, can learn to use it in a day or so. I would like to have all screen functions in the designer or not use the designer at all.

Thanks again, I really appreciate your help.

jpn
22nd January 2007, 23:36
This is the "example" I have been referring to:



QButtonGroup* grp = new QButtonGroup(this);
grp->addButton(ui.pb1, 1);
grp->addButton(ui.pb2, 2);
...
grp->addButton(ui.pb12, 12);
connect(grp, SIGNAL(buttonClicked(int)), this, SLOT(slotPb(int))

void PmForm::slotPb(int id)
{
ui.leZone->setText(QString("This is Pb%1").arg(id));
}


Many people (especially the ones switching from Qt3 to Qt4) tend to criticize Qt Designer. In my humble opinion it's just a great tool for it's purpose, designing GUI layouts. I guess the main reason for not including QButtonGroup in Designer is because it's not a widget but a functionality class. The Designer is for designing layouts, you code the functionality.

FAQ (http://www.qtcentre.org/forum/faq.php?faq=qt_designer_category):


Beginning with Qt4.0 Qt Designer seized to be an all-purpose development environment and became strictly a GUI Designer which can easily be incorporated into real IDEs like Visual Studio, Eclipse or KDevelop.


According to this poll (http://www.qtcentre.org/forum/f-qt-programming-2/t-qt-designer-coding-by-hand-3099.html), most people on this forum still seem to be happy with and using the Designer.

Anyway, there's a related entry in the Task Tracker: 126997 - Suggestion: QButtonGroup in Designer (http://www.trolltech.com/developer/task-tracker/index_html?method=entry&id=126997). Maybe in the future you can setup button groups from the Designer..

I'd say it's not about the age but the passion. You're not too old as long as you have any personal interest into programming. Of course amnesia and such might make it harder but... ;)

impeteperry
23rd January 2007, 01:55
Philosophical reasons aside, what is the real difference betwee the 12 + lines of code to build the button group and the 12 signal-slots?

wysota
23rd January 2007, 06:52
Anyway, there's a related entry in the Task Tracker: 126997 - Suggestion: QButtonGroup in Designer (http://www.trolltech.com/developer/task-tracker/index_html?method=entry&id=126997). Maybe in the future you can setup button groups from the Designer.
I strongly doubt that (I haven't read the task-tracker entry though) as it will greatly limit the capabilities of the button group. Most people will not even look at the docs to see QButtonGroup is something more than what can be set from within Designer (i.e. adding buttons with different parents).


what is the real difference betwee the 12 + lines of code to build the button group and the 12 signal-slots?

Clarity of code, speed of execution and sanity of the person maintaining the code. And besides that such solution is less error prone.

impeteperry
23rd January 2007, 15:33
Hi mysota
Understood
thanks