[Kde-perl] Why isn't this easy? implementing File->New
Andrew Snyder
asnyder at ariasystems.net
Wed Aug 2 20:05:57 CEST 2006
I'd go with a package scoped variable. Any reason why this wouldn't work?
package MyView;
our %window_list;
...
...
sub NEW {
...
$window_list{$self}++;
...
}
sub DESTROY
{
my $self = shift;
if (defined $window_list{$self})
{
delete $window_list{$self};
}
...
}
On Wednesday 02 August 2006 12:38, Joe Carlson wrote:
> Darrik and Ashley,
>
> Thanks for the info. I appreciate the 'garbage collection done him
> wrong' advice. This is definitely it.
>
> But I have now a comment or two about these methods. It seems like all
> of these are ways to create references to the newly created top-level
> windows to keep the reference count from going to zero and getting
> destroyed. But it seems to me that this needs to be done at a global (or
> application) level. If I keep a list of the new windows I've created
> within the first window, what happens when I close the first window? In
> trying out different things, I'm seeing that the created windows also
> close. (Of course maybe it's some quirk about how I've scoped
> variables...) There are some cases where closing the creating window
> also closes the created, but this isn't what I'm looking for. I was
> trying out Darrik's hash-the-reference approach and seeing this
> behavior. (In addition, it seemed to me that if I opened a third window
> after opening one from from the first, the second window closed. Again,
> maybe that was a scoping issue.)
>
> What I see as the simplest way to beat the garbage collection is to
> simple put a self reference in the class
>
> package MyView;
> ...
> use Qt::attributes qw(selfReference ...);
> ...
> sub NEW {
> ...
> selfReference = this;
> ...
> and so on.
>
> In my playing around, this gives me all the right behavior. But if
> future collectors get more clever and see that this is a circular
> reference all bets are off. The only iron clad way to keep the reference
> is to make a list a global scope
>
> push @main::windowList, $newWindow;
>
> But now here's the thing: this now is reproducing the C++ behavior,
> warts and all. The C++ code is simple, I just 'new' me up a main window
> and call show on it. And we've manage to make it this simple in the perl
> code. But we've just created a memory leak since we've made no
> allowances for freeing memory after the created windows are closed.
>
> If I use the self-reference trick, then I need to reset this before
> calling close:
>
> sub processFileMenu {
> ...
> if ($option == FILECLOSE) {
> selfReference = '';
> this->close();
> }
> ...
>
> I've been testing this out with print's in the module's DESTROY method
> and things seem to be cleaning up properly. I'm going to try this out.
> The only other option I can think of is to use the application level
> list and emit signal when there is a request to close the top level
> window and have the application deal with removing the reference from
> the list.
>
> Thanks,
>
> Joe
>
> On Tue, 2006-08-01 at 23:12 -0700, Ashley Winters wrote:
> > --- darrik <darrik at mythofbutterfly.com> wrote:
> > > Ashley Winters wrote:
> > > > use strict;
> > > > use Qt; # use Qt in EVERY package! It declares 'this', and does
> > > > other use-strict-happy things
> > > > use MyView;
> > > > sub processFileMenu {
> > > > if ($option==FILENEW) {
> > > > MyView(this)->show;
> > > > }
> > > > }
> > >
> > > You're not storing a perl reference to the new window anywhere. What
> > >
> > > happens when you want to access that window from the parent later?
> >
> > Ahh, in that case you want to store it as a member variable. If, for
> > example, we wanted to populate the Window menu with the list of windows
> > opened with File->New or something...
> >
> > package YourClass;
> > use strict;
> > use Qt;
> > use Qt::isa qw(Qt::Widget);
> > use Qt::attributes qw(windows); # declare a member variable
> > use MyView;
> >
> > sub NEW {
> > # standard preamble
> >
> > windows = []; # initialize as an array
> > }
> >
> > sub processFileMenu {
> > if ($option==FILENEW) {
> > my $viewer = MyView(this);
> > $viewer->show;
> > push @{ windows }, $viewer;
> > }
> > }
> >
> > > This is more evident when you subclass a container widget that has
> > > child
> > > controls. For instance:
> >
> > I'll make the edits inline...
> >
> > > use strict;
> > >
> > > package MyWidget;
> > >
> > > use Qt;
> > > use Qt::isa qw( Qt::Widget );
> >
> > use Qt::attributes qw( lbl );
> >
> > > sub NEW {
> > > # irrelevant method arguments left out for brevity :P
> > >
> > > my $class=shift;
> > > my $parent=shift;
> > > shift->SUPER::NEW($parent);
> > > my $layout=Qt::HBoxLayout(this);
> >
> > #> my $lbl=Qt::Label("label",this);
> > #> $layout->addWidget($lbl);
> >
> > # instead
> > lbl = Qt::Label("label",this);
> > $layout->addWidget(lbl);
> >
> > > }
> > >
> > > sub changeChildLabel {
> > > # how do you access $lbl here?
> >
> > lbl->setText("Qt::attributes");
> >
> > > }
> > >
> > >
> > > This part has me confused. Storing $lbl in a package variable
> > > doesn't
> > > work if you instantiate several MyWidget's. I've been using
> > > workarounds
> > > that are inelegant, so a pointer to the *proper* way to do this would
> > > be
> > > immensely appreciated.
> >
> > Sure. Keep in mind that the 'this' function/variable/keyword thing is,
> > in fact, a hash. You're free to store things in it, like so:
> >
> > this->{'lbl'} = Qt::Label(...);
> >
> > In fact, that's all the Qt::attributes pragma does, is setup that
> > shortcut. It automatically creates a lbl() function which returns
> > this->{'lbl'}, in a way that lets you assign to it (as an lvalue).
> >
> > That's the technical side, at least. For more of a tutorial, read this:
> >
> > http://perlqt.sourceforge.net/dist/current/doc/en/index.html#using_attrib
> >utes
> >
> > - Ashley Winters
> >
> > __________________________________________________
> > Do You Yahoo!?
> > Tired of spam? Yahoo! Mail has the best spam protection around
> > http://mail.yahoo.com
> > _______________________________________________
> > Kde-perl mailing list
> > Kde-perl at kde.org
> > https://mail.kde.org/mailman/listinfo/kde-perl
>
> _______________________________________________
> Kde-perl mailing list
> Kde-perl at kde.org
> https://mail.kde.org/mailman/listinfo/kde-perl
--
Andrew Snyder
More information about the Kde-perl
mailing list