PDA

View Full Version : Multiple parents; not inheritance



tescrin
9th August 2012, 17:25
I'm looking to use what I consider an "elegant" solution of having the same child have multiple parents; The reason being the only things these dialogs share are a few buttons; but I figured if I could figure out how to give the same thing multiple parents then it reduces the duplicate work. The only times these buttons have unique operations called on them (outside of their menus and things) are from their parents calling "hide" and such (implicitly.)

I'm assuming you can't do this since you pass in a parent pointer at the beginning, and merely having the child object's pointer in the class is probably not enough (since Qt won't consider it an official parent; as we haven't passed in the second parent's pointer.)

Thoughts?

high_flyer
9th August 2012, 17:33
I'm looking to use what I consider an "elegant" solution of having the same child have multiple parents;
Are you talking about children as "Child is derived from Parent" or as "Child is a member of Parent"?
From your text it seems as you are mixing the two.

amleto
9th August 2012, 19:26
I'm looking to use what I consider an "elegant" solution of having the same child have multiple parents; The reason being the only things these dialogs share are a few buttons; but I figured if I could figure out how to give the same thing multiple parents then it reduces the duplicate work. The only times these buttons have unique operations called on them (outside of their menus and things) are from their parents calling "hide" and such (implicitly.)

I'm assuming you can't do this since you pass in a parent pointer at the beginning, and merely having the child object's pointer in the class is probably not enough (since Qt won't consider it an official parent; as we haven't passed in the second parent's pointer.)

Thoughts?

Qt has very exact rules for what happens when something has a parent. The framework rules will only allow for one parent.

Making two instances of the same class and giving them to different parents IS NOT duplicate work, so I don't know what you are getting at.

tescrin
9th August 2012, 19:47
Right, I was assuming as much; but I wanted to ask.

@high_flyer, I was talking about both.. sort of. I meant a has-a relationship when I was speaking about traditional C++ and how that wouldn't imply anything in Qt. In Qt a has-a relationship when initialized with a "this" (or some other Qobject) denotes a child parent relationship regardless (IIRC.)

@amleto ...and thus (continuing from the above) I was wondering if there was any neat functionality like a constructor that could build *two* parent relationships such as MyWidget(*parent1 = somewidget, *parent2 = someotherwidget);

I knew it was a stretch but for all I knew there'd be a simple workaround to it or it would exist.


The idea was that I could do something like:
parent1->hide(); (which hides all of it's qchildren)
and
parent2->show(); (which shows all of it's qchildren)

and by this button having both parents it remains abstracted from the View Manager class I'm using but shows in both windows in an elegant way; I.E. not hardcoding it to show in both windows but showing only when it's appropriate.



My question (tangled up with the other one) was also if there was some way (without modifying show() and hide(), though that is a possibility) to perform such functionality; by putting some reference in each one somehow. I'm attempting to avoid duplicating the same QWidget in multiple windows (in terms of code) while having it show in each window *without hardcoding it in.* Now, there's no real reason I *can't* hardcode it, it's just dirty. I could also pull it up to the parent of these two.. parents, but that means the view-manager is dealing with dirty details instead of delegating; which I figured is unintuitive were someone to play with my code later.

Does that clear it up a bit? Thank you for any ideas you might put forth

amleto
9th August 2012, 20:12
does it clear it up? No. Just use two instances. There is no need to hard code anything or to duplicate code. Just use basic composition/aggregation.

alitoh
9th August 2012, 20:31
does it clear it up? No. Just use two instances. There is no need to hard code anything or to duplicate code. Just use basic composition/aggregation.

I just want to add to this that, from what I understood, you are mixing two very different concepts. It seems to me you wish to connect (http://doc.qt.nokia.com/4.7-snapshot/signalsandslots.html) two "parents" to the same widget. That way, you want to create a certain relationship between those 3.

If it's not about events but, rather, as a simple visibility issues, you might just want to just make a custom QFrame widget that recieves a QWidget pointer as parameter, then add that to a layout inside the QFrame.

You don't need to duplicate anything. You either have two instances of your class working, or you can make it so that you pass a reference to the widget you do not want to duplicate and then handle it in two different places. This last way to do things is dangereous, as you will have to handle if the pointers do have access to said memory (if you delete it in one "window" your application will crash when you try to show it in the other one, etc), and other stuff that might come up.

I don't think memory is that much of a concern that you cannot afford to instantiate a new widget, so you might want to rethink your problem because, from MY position, what you suggest doesn't seem that easy or elegant to use and implement.

Also, you might want to read on the Ownership (http://doc.qt.nokia.com/4.7-snapshot/objecttrees.html) documentation, because it doesn't feel like your concept of parenting is quite right.

tescrin
9th August 2012, 21:35
I'll go check that out and see if I have any revelations. All I was saying is that the parent, because of the way they work as containers or other objects, auto-hides/shows it's children. If it were possible to have it be a "child" of two separate Qdialogs (for example) then when you hide one and show the other they'd each use the same instance of the button.. I think.

Maybe this is the problem lol. I'll go read..


I may just have to solve it by having two instances. Ho hum.

alitoh
9th August 2012, 21:52
In that case your button wouldn't be a children of both QDialogs but, rather, of the bigger container that also contains the two QDialogs. You need, however, to make sure that if you operate with the memory itself of one of the pointers, it will directly affect how the other one behaves. If you delete the button reference in one of the QDialogs, the other one will immediately crash when trying to access system memory.

This is how I am visualizing what you might need right now.
8118

amleto
10th August 2012, 01:47
I'll go check that out and see if I have any revelations. All I was saying is that the parent, because of the way they work as containers or other objects, auto-hides/shows it's children. If it were possible to have it be a "child" of two separate Qdialogs (for example) then when you hide one and show the other they'd each use the same instance of the button.. I think.

Maybe this is the problem lol. I'll go read..


I may just have to solve it by having two instances. Ho hum.

A widget can't have two parents. A widget can't be in two layouts. Them's the rules! It's just a button, make two of them - what is the big deal?

alitoh
10th August 2012, 02:27
A widget can't be in two layout

Are you 100% sure? I cannot test this right now nor in the few next days, but I would be inclined to doubt that.

luckyboy
10th August 2012, 06:09
In that case your button wouldn't be a children of both QDialogs but, rather, of the bigger control that also contains the two QDialogs..!

tescrin
13th August 2012, 17:05
Oh very cool! In fact the dialogs that would share it *are* contained within the same class. I'll keep this in mind as I go about designing :). The basic idea is that this is a problem I'll be running into as I reproduce a large number of dialogs for a certain machine. Several of them end up using the same data, the same button, etc.

The VB6 code of a similar program does this by having the buttons contained in "controllers" and then adds the same controller to multiple windows (or dialogs.) I'm not looking to make my version needlessly cluttered with 100's of classes/controllers for simple button differences. Rather, I'd like it to be as clean, crisp, and small as possible; hence this and other odd questions on the forum. Answers like this one imply to abstract up, which is a fine approach and gives good direction.

There's so much to learn in Qt and it does so much behind the scenes it's hard to figure out the more advanced interactions it might have while I'm still getting used to some of the mundane ones. Doing things "right" the first time, or close enough to it anyway, is a personal goal I guess.

d_stranz
13th August 2012, 18:47
Oh very cool! In fact the dialogs that would share it *are* contained within the same class. I'll keep this in mind as I go about designing . The basic idea is that this is a problem I'll be running into as I reproduce a large number of dialogs for a certain machine. Several of them end up using the same data, the same button, etc.

Boy, you're asking for trouble if you keep going down this road. It isn't clear to me why you are trying to optimize something so trivial in its memory footprint as a push button (or any other simple widget for that matter) by trying to share a single instance among multiple dialogs.

Is the problem you are trying to solve one where a button that appears on more than one dialog needs to execute the same code when it is clicked? (Like an "Apply" button that triggers the same application-level response no matter what dialog it appears on?) Then use QAction. Create the QAction instance as a child of your application's main window, connect its triggered() signal to whatever slot you want to do the app-level processing, then add that action to each of the QPushButton instances you want to trigger the action (using QWidget::addAction()).

tescrin
13th August 2012, 19:31
It's not that I'm worried about memory management, it just seems to be lazy design (no offence!) to make replicas of the same button with the same display and the same functionality and make two buttons that do *all of the exact same things with the same data, same menu options etc* if a pointer to the button in two places keeps you from having these replicas.

I'm unsure which is better still, whether I should have this "third party button" shared between dialogs, or if I should just make two buttons and connect the same menus/actions. I'm probably being "young and stupid" by worrying too much about a general solution and just accept that sometimes the better way to go is to have two copies of something.

d_stranz
13th August 2012, 20:09
Well, as others have said, you can't share QObject instances. if you add a button to one dialog, that sets its parent, and that parent controls its lifetime. If you transfer it to a different dialog, then ownership switches to the new dialog parent and it disappears from the first one. If you create your dialogs on the stack, then you have to be very careful to remove these shared children *before* the dialog goes out of scope, other wise the dialog will delete them and you'll be left with invalid dangling pointers.


I'm probably being "young and stupid" by worrying too much about a general solution and just accept that sometimes the better way to go is to have two copies of something.

Sort of what I'm thinking :-) But you're still confusing widget instances with widget code. You don't have "two copies of something". You have different buttons on different dialogs that just happen to do the same thing. If they do all of the same things, then you aren't duplicating code when you bundle their response to user interactions up into actions. The same QAction instance can be shared among any number of QWidget instances, and the slot it executes is a single piece of non-duplicated code. And even if you don't use QAction, but connect the push button signals all to the same slot, you still haven't duplicated anything except the tiny bit of memory used to hold each discrete button instance and its member variables. There's only one copy of the button's code, period.

So why spend so much time trying to defeat Qt when working with it is so much simpler and less prone to errors?

amleto
13th August 2012, 22:46
exactly. How long have you spent trying to solve this 'problem'? Just use widgets how they are meant to be used and you save hours.