Share your knowledge at the LQ Wiki.
Go Back > Blogs > rainbowsally
User Name


Rate this Entry

GUI coding. A peek at run-time inheritance (method lookups)

Posted 04-20-2012 at 09:23 AM by rainbowsally
Updated 04-20-2012 at 09:26 AM by rainbowsally

GUI coding. A peek at run-time inheritance (method lookups)

In previous blog entries we built QT's example/desktop/screenshot application and did a bit of tracing with a debugger.

Let's take a look at the metaobject definition file (moc_screenshot.cpp) next.

This is where QT implements a class' method inheritance. It looks up 'methods' from the widget's parent first, then if parent doesn't handle the '_id' we try it here, and if we don't handle it we subtract the number of methods we DO implement and pass the result back to whoever called us -- which could be another widget which could be a child of this one.

This is pretty cool.

int Screenshot::qt_metacall(QMetaObject::Call _c, int _id, void **_a)
  _id = QWidget::qt_metacall(_c, _id, _a);
  if (_id < 0)
    return _id;
  if (_c == QMetaObject::InvokeMetaMethod) {
    switch (_id) {
      case 0: newScreenshot(); break;
      case 1: saveScreenshot(); break;
      case 2: shootScreen(); break;
      case 3: updateCheckBox(); break;
      default: ;
    _id -= 4;
  return _id;
If this widget had no parents and only had one method, for case 0, it would subtract 1 if it executed, returning -1, notifying the caller (possibly a child widget) that the method was at least within range, and presumably had been handled.

If the id was out of range, it would return the original _id - 1.

So if this were called by a a child widget whose id's also start at 0 now having the id decremented by its parent's number of methods (1 in this case), would execute the method for case 0 when it initially received an _id = 1.

Sorry if that's confusing. Let's look at this another way.

If a child of the actual Screenshot class had one _id, it's case switch would be case 0. But to execute it you'd have to pass it an _id of 4 (IF Screenshot had NO parent methods), and Screenshot would subtract 4 from the _id when it returned, and we'd then handle case 0.

For C/C++ newbees:

In actual fact, however Screenshot does have parent methods. How many?

Need a clue? See 'qt_meta_data_Screenshot' in the moc_screenshot.cpp file.

[Ans: ten.]

Okay then, what _id would you have to send to this metaobject to execute it's 'shootScreen' method? What parameters and what types would they have to be in order to avoid crashing in the C++ call?

Yer on your own for that one. :-)

Then rewrite the moc_screenshot case switch to use A, B, C, D instead of 0,1,2,3, and add:

[We CAN do this with our own makefile system!]

enum // as a typedef and named if you know how to get it to compile that way.
A = 0,

Is there an advantage to using enums rather than QTs numeric _id system? Is there a disadvantage? (Requires disassembly, use objdump -d o/moc_* to see it.)

[Ans: nope. Not with gcc 4.5 anyway. No difference at all.]

For C/C++ intermediate and advanced guys:

How would you parse a header file to generate enums for calling various functions declared in that header that would allow changes (addition or deletion) in a parent's chain of methods (possibly loaded in a shared object -- i.e, possibly no headers for the parent chain) without skewing and screwing up the method IDs in the current set of methods?

How would you assure that a method id that once referred to a function that was present in one specific class or file but, had been removed, doesn't call the wrong method without doing a time consuming name lookup and comparison?

Posted in Uncategorized
Views 414 Comments 0
« Prev     Main     Next »
Total Comments 0




All times are GMT -5. The time now is 01:53 AM.

Main Menu
Write for LQ is looking for people interested in writing Editorials, Articles, Reviews, and more. If you'd like to contribute content, let us know.
Main Menu
RSS1  Latest Threads
RSS1  LQ News
Twitter: @linuxquestions
Facebook: linuxquestions Google+: linuxquestions
Open Source Consulting | Domain Registration