Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
dev:layout_code [2009/06/27 22:15]
michael
dev:layout_code [2013/07/21 13:00]
tedfelix [Let Qt 4 manage your parents] this? addWidget()
Line 52: Line 52:
 </code> </code>
  
-All of this vBox begat frame begat QPushButton code can be removed for simplicity.  It is rarely necessary or beneficial to supply all these optional parent parameters.  This has many practical advantages, and has been greatly helpful to me in resolving broken layouts during this restructuring work.  If an existing layout ain't broke, there is little point in fixing it, but please do not write code like this in new layouts.  The example above will work perfectly fine when reduced to:+All of this vBox begat frame begat QPushButton code can be removed for simplicity.  (QLayout::addItem() which is eventually called by addWidget() will take ownership of the widget.  So there is no danger of memory leaks.)  It is rarely necessary or beneficial to supply all these optional parent parameters.  This has many practical advantages, and has been greatly helpful to me in resolving broken layouts during this restructuring work.  If an existing layout ain't broke, there is little point in fixing it, but please do not write code like this in new layouts.  The example above will work perfectly fine when reduced to:
  
 <code c++> <code c++>
Line 65: Line 65:
 </code> </code>
  
-Furthermore, it seems to be widely accepted Qt 4 idiom to create most objects with no or few initialization parameters, and then use member functions to set things up after creation.  This makes for very clean, clear code that is easy to follow.+===== Fewer parameters at object creation =====
  
-[Real example TBAI'm looking for something like+In the pastit used to be common to create Qt objects with all kinds of parameters, including an optional name.  We have an abundance of code like this example:
  
-m_foo = new QWhatzit(myParentheightwidth, favoritePoison, name);+<code c++> 
 +    m_dialogButtonBox = new QDialogButtonBox sbuttonsQt::Horizontalthis ); 
 +    m_dialogButtonBox->setObjectName ( "dialog_base_button_box" ); 
 +    m_mainLayout->addWidget ( m_dialogButtonBox ); 
 +</code>
  
-becoming+The QDialogButtonBox is created with three parameters, and then the object's name is set with a follow-up call to setObjectName() that looks like it is probably the result of automatic conversion, as none of the modern ctors for this class take a name parameter:
  
-m_foo = new QWhatzit; +<code c++> 
-m_foo->setHeight(height); +  QDialogButtonBox QWidget * parent = 0 
-m_foo->setWidth(width); +  QDialogButtonBox Qt::Orientation orientation, QWidget * parent = 0 
-m_foo->setFavoritePoison(BEEEEEEEEEEEER);+  QDialogButtonBox StandardButtons buttons, Qt::Orientation orientation = Qt::Horizontal, QWidget * parent = 0 ) 
 +</code>
  
-whenever I run across real one in the code]+We have never done much with the name property, and it is just as well whenever it happens to have been split out of declaration like this one.  Most objects we have named throughout our code have names that serve no particular purpose.  Of the few exceptions to this rule of thumb, almost all meaningful object names are related to our new stylesheet-based look. 
 + 
 +I suggest using the excellent [[http://betterthangrep.com/|ack]] utility to search the code tree for occurrences of any questionable name.  In this case, it looks like "dialog_base_button_box" used to be named for some purpose that is probably no longer valid: 
 + 
 +<code> 
 +src/gui/dialogs/ConfigureDialogBase.cpp 
 +73:    m_dialogButtonBox->setObjectName( "dialog_base_button_box" ); 
 +231:    //QDialogButtonBox *dbb = findChild<QDialogButtonBox *>( "dialog_base_button_box" ); 
 + 
 +src/gui/studio/SynthPluginManagerDialog.cpp 
 +128:        m_dialogButtonBox->setObjectName ( "dialog_base_button_box" ); 
 +</code> 
 + 
 +The call to findChild has been commented out without causing any observed problems in the past 656 revisions.  Still, just in case, we'll leave it for now and move on. 
 + 
 +Of the remaining parameters in the declaration: 
 + 
 +<code c++> 
 +    m_dialogButtonBox = new QDialogButtonBox ( sbuttons, Qt::Horizontal, this ); 
 +</code> 
 + 
 +We can and should remove the parent entirely, and we could use setStandardButtons() and setOrientation().  It is not such a big deal to refactor changes like these last two in current code, but it is a good idea to use this kind of idiom in the future.  The entire code snippet, then, could be written out like this: 
 + 
 +<code c++> 
 +    m_dialogButtonBox = new QDialogButtonBox; 
 +    m_dialogButtonBox->setObjectName("dialog_base_button_box"); 
 +    m_dialogButtonBox->setStandardButtons(sbuttons); 
 +    m_dialogButtonBox->setOrientation(Qt::Horizontal); 
 +    m_mainLayout->addWidget(m_dialogButtonBox); 
 + 
 +</code>
  
 +It is true that this requires more typing, but it saves having to browse Qt documentation to find out what the parameters are when revisiting old code, and it doesn't take code very long at all to become old in terms of remembering what does what.  Just in the six or so months I've been most deeply involved with all this layout work, I've really learned to appreciate the examples where I did the kind of refactoring I'm promoting as the good practice standard here.
  
 ===== You Can Set A Layout Before You Populate It! ===== ===== You Can Set A Layout Before You Populate It! =====
 
 
dev/layout_code.txt · Last modified: 2022/05/06 16:07 (external edit)
Recent changes RSS feed Creative Commons License Valid XHTML 1.0 Valid CSS Driven by DokuWiki