Results 1 to 20 of 20

Thread: Partial Qt Designer built forms

  1. #1
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Partial Qt Designer built forms

    I've got a partial form layout built with Qt Designer, the rest of the form is dynamically built at run time during application initialization.

    The auto generated code by Qt Creator adds a call to QMetaObject::connectSlotsByName at the end of the setupUi function. I'd like to defer this call until after the UI is built at run time. Is there a switch in Qt Designer or Creator to suppress generating that line of code?

    If need be, a pre build step to strip the line of code from the generated header could be done before compiling, but I'd rather not go that route.

    TIA,
    Paul

  2. #2
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    The auto generated code by Qt Creator adds a call to QMetaObject::connectSlotsByName at the end of the setupUi function.
    I can't test at the moment, but as far as I know, this is done by the moc, not by the uic.
    The uic as far as I can remember, only generates a header, which initialized the gui elements.
    The signal/slot connections are done by the moc.
    But I might be wrong, as I said, I can't test here at the moment.
    If I am right, your problem is not with the code generated by uic.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  3. #3
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Thanks high_flyer,

    After running some tests and looking at the source for connectSlotsByName, I have a clearer picture of what is happening behind the scenes. My misunderstanding was that connectSlotsByName(this) would auto magically match up all the children and relative slots of this with other children and relative signals.

    Now it's my understanding, when connectSlotsByName(this) is called that only slots of this will be matched up with the child objects with matching signals.

    About ui_MainWindow.h and connectSlotsByName being called in setupUi - would be nice to disable that call from being generated, so it can be called later after the full UI is initialized.

    Thanks again h_f.

  4. #4
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    setupUi() is not called in the auto generated code, but in your code... or I misunderstood you...
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  5. #5
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by high_flyer View Post
    setupUi() is not called in the auto generated code, but in your code... or I misunderstood you...
    Correct, from the constructor of the derived class QMainWindow.
    Qt Code:
    1. MainWindow::MainWindow(QWidget ...)
    2. {
    3. ui.setupUi(this);
    4. // UI is only partially built from Qt Designer, connectSlotsByName
    5. // is called in setupUi.
    6.  
    7. BuildRestOfUI(this);
    8. // Can't call connectSlotByName a second time, otherwise each signal
    9. // slot pairing from the previous call will add another signal slot pairing
    10. // resulting in those slots getting 2 signals (called twice).
    11. }
    To copy to clipboard, switch view to plain text mode 
    Qt Code:
    1. //** Form generated from reading UI file 'MainWindow.ui'
    2. void setupUi(QMainWindow *MainWindowClass)
    3. {
    4. if (MainWindowClass->objectName().isEmpty())
    5. MainWindowClass->setObjectName(QString::fromUtf8("MainWindowClass"));
    6. MainWindowClass->resize(766, 542);
    7. actionNew = new QAction(MainWindowClass);
    8. actionNew->setObjectName(QString::fromUtf8("actionNew"));
    9. // >>snip<<
    10. retranslateUi(MainWindowClass);
    11. QMetaObject::connectSlotsByName(MainWindowClass);
    12. } // setupUi
    To copy to clipboard, switch view to plain text mode 

  6. #6
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Oh now I see what you mean (I think) - you DO want to call setupUi() when you do, but you don't want it to call the signal/slot auto connection at that time, is that correct?
    Do you have to use auto-connect?
    If you don't - you can delete the connections done by designer, this way setupUi() will not call the connections, and you can make the connections at any time later that suits you.

    If you have to use the auto connections, then maybe you need a different approach.
    Have a look at QAbstractFormBuilder, it might give you the flexibility you want, without giving up on the ui files.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  7. The following user says thank you to high_flyer for this useful post:

    pkohut (29th December 2010)

  8. #7
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Partial Qt Designer built forms

    I would suggest to not rely on connectSlotsByName() at all and instead make all the connections manually. auto-connecting slots is a dirty hack that shouldn't be used as it requires the slots to have weird names and the mechanism often backfires if you name slots in this manner by accident and you end up with a double connection or no connection at all (if you rename some object later on).
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  9. The following user says thank you to wysota for this useful post:

    pkohut (29th December 2010)

  10. #8
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by high_flyer View Post
    Oh now I see what you mean (I think) - you DO want to call setupUi() when you do, but you don't want it to call the signal/slot auto connection at that time, is that correct?
    Correct.
    Quote Originally Posted by high_flyer View Post
    Do you have to use auto-connect?
    If you don't - you can delete the connections done by designer, this way setupUi() will not call the connections, and you can make the connections at any time later that suits you.
    Prior to the initial posting I did that, however the results were unexpected (to me). Here's the code. Running it with QMetaObject::connectSlotsByNames commented out in setupUi resulted in found connections (wasn't expecting any). Will do some research as to what connections those are and if safe to disconnect and will they reconnect with a later call to connectSlotsByNames. Post findings later.

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
    2. : QMainWindow(parent, flags)
    3. {
    4. ui.setupUi(this);
    5. bool bFoundConnections = false;
    6. foreach(QObject * obj, this->children()) {
    7. bFoundConnections |= obj->disconnect();
    8. }
    9.  
    10. if(bFoundConnections) {
    11. qDebug() << "It appears QMetaObject::connectSlotsByName was called"
    12. << "in ui.setupUi, make sure that line of code is commented out.";
    13. }
    14. BuildResultOfUi(this);
    15. }
    To copy to clipboard, switch view to plain text mode 

    Quote Originally Posted by high_flyer View Post
    If you have to use the auto connections, then maybe you need a different approach.
    Have a look at QAbstractFormBuilder, it might give you the flexibility you want, without giving up on the ui files.
    Don't need auto connections, just trying to come out of the stone age of hand coding every thing.

    Thanks very much for your help.


    Added after 5 minutes:


    Quote Originally Posted by wysota View Post
    I would suggest to not rely on connectSlotsByName() at all and instead make all the connections manually. auto-connecting slots is a dirty hack that shouldn't be used as it requires the slots to have weird names and the mechanism often backfires if you name slots in this manner by accident and you end up with a double connection or no connection at all (if you rename some object later on).
    That's a good point. There is one slot/signal pair so far that just won't auto connect (spent about 30 minutes on it so far), I'm sure it's syntax, however it looks correct.
    Last edited by pkohut; 28th December 2010 at 20:59.

  11. #9
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Don't need auto connections, just trying to come out of the stone age of hand coding every thing.
    Like wysota, I don't like auto connections, and never used them.
    Nothing stone aged about connecting your self (IMHO) - its a matter of control over your code.

    If you don't need auto connections, and even better, if you don't need the connections done at ui design time (in designer) just get rid of them (any connections in the ui), make them manual - it will save you all the this headache!
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  12. #10
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Partial Qt Designer built forms

    As a side note, there is a quick way to disconnect all connections made to an object so a potential solution to your problem is to do just that (by iterating over children and calling disconnect() variant that breaks all the connections between objects) and then to call connectSlotsByName() when you need it. But I really advise you to not use it and instead make all the connections conciously.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  13. #11
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by wysota View Post
    As a side note, there is a quick way to disconnect all connections made to an object so a potential solution to your problem is to do just that (by iterating over children and calling disconnect() variant that breaks all the connections between objects) and then to call connectSlotsByName() when you need it. But I really advise you to not use it and instead make all the connections conciously.
    I'm taking the advise of you and high_flyer and forgoing auto connections. However, was still wondering if breaking the connections then calling connectSlotsByName would be sufficient. From the code below I'd say the answer is no.

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent, Qt::WFlags flags)
    2. : QMainWindow(parent, flags)
    3. {
    4. // connectSlotsByName called in setupUi
    5. ui.setupUi(this);
    6.  
    7. // Get count of disconnected slots and signals
    8. int nConnectionsA = 0;
    9. foreach(QObject * pObj, this->children())
    10. nConnectionsA += pObj->disconnect();
    11.  
    12. // reconnect slots by name
    13. QMetaObject::connectSlotsByName(this);
    14.  
    15. // Get count of disconnected slots and signals
    16. int nConnectionsB = 0;
    17. foreach(QObject * pObj, this->children())
    18. nConnectionsB += pObj->disconnect();
    19.  
    20. // Test run here nConnectionsA == 9 and
    21. // nConnectionsB == 0
    22. Q_ASSERT(nConnectionsA == nConnectionsB);
    23. }
    To copy to clipboard, switch view to plain text mode 

  14. #12
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Your code is not doing what you wanted to do:
    Qt Code:
    1. int nConnectionsA = 0;
    2. foreach(QObject * pObj, this->children()){
    3. if( pObj->disconnect())
    4. nConnectionsA ++;
    5. }
    6.  
    7. // reconnect slots by name
    8. QMetaObject::connectSlotsByName(this);
    9.  
    10. // Get count of disconnected slots and signals
    11. int nConnectionsB = 0;
    12. foreach(QObject * pObj, this->children()){
    13. if( pObj->disconnect())
    14. nConnectionsB ++;
    15. }
    To copy to clipboard, switch view to plain text mode 
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  15. #13
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by high_flyer View Post
    Your code is not doing what you wanted to do:
    Hmm, what did I miss? QObject::disconnect() returns type bool. Through implicit conversion from type bool to type int , true is 1 and false is 0.

    Just to make sure it isn't a compiler thing I tested this is VC and gcc.
    Qt Code:
    1. bool bVal = (bool) 200;
    2. int nVal = bVal;
    3. qDebug() << bVal << nVal;
    To copy to clipboard, switch view to plain text mode 
    Output is: true 1

  16. #14
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,709
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    You are right.
    But I think such tings are potentially dangerous.
    Since true doesn't necessarily has to mean '1' (all though I just checked, and the c++ indeed specifies true as '1').
    But some environments or applications redefine bool,
    But in this case you are right.

    what does this->children().size() return in both cases?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  17. #15
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by pkohut View Post
    However, was still wondering if breaking the connections then calling connectSlotsByName would be sufficient.
    But what is the point of doing so? Could you tell me what the following slot does?

    Qt Code:
    1. void Cls::on_btn4_clicked() { /* ??? */ }
    To copy to clipboard, switch view to plain text mode 

    Isn't it better to call it say... "chooseBrushColor()" instead?
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  18. #16
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by high_flyer View Post
    You are right.
    But I think such tings are potentially dangerous.
    Since true doesn't necessarily has to mean '1' (all though I just checked, and the c++ indeed specifies true as '1').
    But some environments or applications redefine bool,
    But in this case you are right.
    Integral promotion rules for type bool are explained in the C++ standard, sections 3.9.1.6, 4.5.4, and 4.12.


    Added after 34 minutes:


    Quote Originally Posted by wysota View Post
    But what is the point of doing so? Could you tell me what the following slot does?
    Qt Code:
    1. void Cls::on_btn4_clicked() { /* ??? */ }
    To copy to clipboard, switch view to plain text mode 
    Isn't it better to call it say... "chooseBrushColor()" instead?
    (edit: somehow lost my original response)
    Yes, "chooseBrushColor" is much better than "on_btn4_clicked". However, renaming "btn4" to "btnBrushColor" makes a much more meaningful objectname, which the auto slot connection becomes "on_btnBrushColor_clicked()".

    Qt Designer just provides default place holder names. It's up to the designer/programmer to provide each of the elements better names. Some of the UI elements cannot be seen or edit while in Designer so editing the *.ui file in a text editor is a good idea. For instance, my "centralWidget" has a QVBoxLayout associated with it that cannot be seen in Designer, so in a text editor I've renamed the non sensible name to "centralWidgetVLayout", and as long as the layout isn't changed to horizontal then the name makes since.

    The slots/signals paradigm is new territory for me, but correct me if I'm wrong, wouldn’t better object names make the auto connection less error prone to use? With only a couple days playing around with slots/signals I can't make an informed call.

    Still with the ui_MainWindow.h file having that blasted QMetaObject::connectSlotsByName called in setupUi and my partial form at the time of the call, auto connections won't do me much good anyway (still need to look into QAbstractFormBuilder).

    Thanks again.
    Last edited by pkohut; 29th December 2010 at 12:49.

  19. #17
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by pkohut View Post
    Yes, "chooseBrushColor" is much better than "on_btn4_clicked". However, renaming "btn4" to "btnBrushColor" makes a much more meaningful objectname, which the auto slot connection becomes "on_btnBrushColor_clicked()".
    What if you have two places where you trigger choosing the brush color? You either end up with two identical slots (on_btnBrushColor_clicked and on_SomethingElse_clicked) or you have to manually connect the SomethingElse object to the on_btnBrushColor_clicked slot which completely defeats the purpose of auto-connecting slots and moreover introduces yet more points where your code can break.

    Qt Designer just provides default place holder names. It's up to the designer/programmer to provide each of the elements better names.
    Designer allows to define custom signal and slot names for the form which makes it possible to make explicit signal/slot connections directly in Designer (by point&click) and then declare implement those slots (and declare signals) in the real QWidget subclass the form is deployed on. That's a much better solution than relying on auto-connect. Search the forum to see how often people end up with double connections by intuitively naming slots in a way that matches the auto-connect scheme and wasting time debugging their apps to find out why slots are triggered multiple times.


    The slots/signals paradigm is new territory for me, but correct me if I'm wrong, wouldn’t better object names make the auto connection less error prone to use?
    My point of view is that a decent programmer should be totally aware of what her/his code is doing thus all connections should be made explicitly in code. The only exception to this rule is (in my eyes) when you are connecting standard signals and slots between objects that are placed on a form in Designer but providing an ability to "predeclare" slots or signals in Designer was not a good design choice by the Trolls although it does simplify life sometimes (which doesn't change the fact it makes the code more prone to errors). Unfortunately in my opinion you need to have some level of skills to be a software developer and can't rely on some tools to do everything automatically for you. It's ok to use the tools if you really understand how they work and what they do. It's five minutes of work to provide your own scheme of auto-connecting signals and slots if you know what makes Qt tick.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  20. #18
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by wysota View Post
    What if you have two places where you trigger choosing the brush color? You either end up with two identical slots (on_btnBrushColor_clicked and on_SomethingElse_clicked) or you have to manually connect the SomethingElse object to the on_btnBrushColor_clicked slot which completely defeats the purpose of auto-connecting slots and moreover introduces yet more points where your code can break.
    >>snip, a bunch of good points<<
    Understood, thanks for the explanation.

    Quote Originally Posted by wysota View Post
    My point of view is that a decent programmer should be totally aware of what her/his code is doing thus all connections should be made explicitly in code. ... Unfortunately in my opinion you need to have some level of skills to be a software developer and can't rely on some tools to do everything automatically for you. It's ok to use the tools if you really understand how they work and what they do. It's five minutes of work to provide your own scheme of auto-connecting signals and slots if you know what makes Qt tick.
    Excellent points. I always hit a wall with GUI builders where they just get in the way, Qt Designer isn't any different.

  21. #19
    Join Date
    Jan 2006
    Location
    Warsaw, Poland
    Posts
    33,363
    Thanks
    3
    Thanked 5,012 Times in 4,791 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows Android Maemo/MeeGo
    Wiki edits
    10

    Default Re: Partial Qt Designer built forms

    Qt Designer doesn't get in the way if you use it properly. Note that you can obtain the exact same functionality with or without it. It's not that there are some magic tricks that work with a graphical tool and don't work in code or the other way round. It's only important that you understand what Designer does and how it does it. Or rather what uic does and how it does it. And the easiest way to learn that is to look at the code uic generates form an ui file.
    Your biological and technological distinctiveness will be added to our own. Resistance is futile.

    Please ask Qt related questions on the forum and not using private messages or visitor messages.


  22. #20
    Join Date
    Dec 2010
    Location
    US, Washington State
    Posts
    54
    Thanks
    3
    Thanked 7 Times in 7 Posts
    Qt products
    Qt4
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Partial Qt Designer built forms

    Quote Originally Posted by high_flyer View Post
    Have a look at QAbstractFormBuilder, it might give you the flexibility you want, without giving up on the ui files.
    This or QFormBuilder looks like it will do the job nicely.

Similar Threads

  1. Need your help with designer plugin built with Creator
    By high_flyer in forum Qt Programming
    Replies: 4
    Last Post: 27th November 2010, 14:46
  2. Designer Forms
    By srohit24 in forum Qt Programming
    Replies: 8
    Last Post: 20th July 2009, 11:28
  3. Replies: 5
    Last Post: 7th May 2009, 14:29
  4. Replies: 7
    Last Post: 5th May 2009, 16:32
  5. Qt Designer forms don't run in 4.2.0
    By Doug Broadwell in forum Newbie
    Replies: 3
    Last Post: 19th October 2006, 12:38

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.