PDA

View Full Version : Howto create custom slot with Designer



gkhrapunovich
26th January 2011, 17:02
I am working on my first Qt project using Designer and Visual Studio 2008 with Qt add-on. In Designer I added a button and connected it to a custom slot. Designer generated connect(...) but it did not add slot function to any .h file. I read FAQ "How can I add a custom slot in Qt4 Designer?" and it says that it's not supported any more. Unfortunately FAQ gives a link to documentation that is broken.

Can somebody point me at tutorial or something explaining how properly add custom slots while using designer? Anything I could find so far describes pure coding and I need to know how to co-exist with designer-generated code.

Thank you.

squidge
26th January 2011, 17:30
You can create the slot function yourself. Designer only regenerates .ui file which UIC will use to regenerate _ui.h, so your .cpp/.h file is safe (will not be modified by designer)

gkhrapunovich
26th January 2011, 19:23
When I tried, my code wasn't called and connect function failed. I was hoping to find an example (with Designer, because it creates a bunch of classes and a namespace).

Added after 1 41 minutes:

OK, I will be more specific. I have created a button btnConnect and from Designer linked signal clicked() with custom slot btnConnect_Clicked(). Designer added the line to generated .h file:

void setupUi(QMainWindow *TcpipClientQtClass)
{
...
QObject::connect(btnConnect, SIGNAL(clicked()), TcpipClientQtClass, SLOT(btnConnect_Clicked()));
}

The problem is that the target class (TcpipClientQtClass) does not have declaration for slot function. And I cannot add it manually because this class is generated by Designer and my change will be overwritten. I created inherited class with this function but it was never called, probably, because it is not declared in the parent. And parent is auto-generated.

How can I get out of this catch-22?

arnaiz
26th January 2011, 20:15
You have to subclass your main window class:


#include <QMainWindow>
#include "ui_mainclass.h"

namespace Ui {
class MainClass;
}

class NewClass : public QMainWindow , public Ui::MainClass
{
Q_OBJECT

public:
NewClass(QMainWindow* parent = 0 ,
Qt::WindowFlags fl = Qt::Window);
~NewClass();
...
public slots:
void yourCustomSlot();

...
Ui::MainClass *ui;
...
};


And then, your NewClass is:


#include "newclass.h"
...

NewClass::NewClass(QMainWindow * parent, Qt::WindowFlags fl) :
QMainWindow(parent)
{
setupUi(this);
...
}

voidYourCustomSlot()
{
...
}



I hope this can help you. :)

gkhrapunovich
26th January 2011, 21:07
Thank you. In my case subclass was already created by the wizard (I am using Qt add-on to Visual Studio). I tried it before but it did not work because I didn't add the line "public slots:". Now everything works.
What is annoying that there is no compiler checks. If I misspell the slot name, the only indication of error will be that slot won't get called.

squidge
26th January 2011, 23:19
You are correct in the fact that there are no compile type checks. Due to the flexibility of the system, this is not possible (eg. you may be connecting signal is some closed source file so only you know the signal names).

However, an error will be generated at run time once the connect method is called stating no such slot or no such signal and the full class name. The return code of the connect call can also be checked, and it's likely that if the connect fails, your unit tests will fail also. So in all, your not going to forget about it :)

gkhrapunovich
27th January 2011, 16:31
Thank you for this note. I knew I could check the return value of connect() but it involved manual editting of compiler-generated file and was very inconvinient. It didn't cross my mind to look at the Output window. Now I see the error message there.