Beefy Boxes and Bandwidth Generously Provided by pair Networks
Just another Perl shrine
 
PerlMonks  

Re: wxPerl fails with a cryptic message: "variable is not of type Wx::Point"

by stefbv (Curate)
on Mar 08, 2013 at 21:39 UTC ( [id://1022500]=note: print w/replies, xml ) Need Help??


in reply to wxPerl fails with a cryptic message: "variable is not of type Wx::Point"

That error was the easiest part..., I made a few changes and fixes and this is the result, to keep the development going :)

package MyForm; use strict; use warnings; use Wx qw[:everything]; # easy when testing use Wx::Event qw(EVT_BUTTON); use base 'Wx::Frame'; use Wx::Perl::ListCtrl; sub new { my $class = shift; my $self = $class->SUPER::new( undef, # parent window -1, # ID -1 means any 'List Control Tutorial', # title [ -1, -1 ], # default position [ 400, 300 ], # size ); # Add a panel so it looks correct on all platforms my $panel = Wx::Panel->new( $self, # parent window -1, # ID ); my $idx = 0; $self->{list_ctrl} = Wx::Perl::ListCtrl->new( $panel, -1, # ID #'Report', # label [ 20, 30 ], # position [ -1, 100 ], # size wxLC_REPORT | wxBORDER_SUNKEN, # window style ); $self->{list_ctrl}->InsertColumn( 0, 'Subject' ); $self->{list_ctrl}->InsertColumn( 0, 'Due' ); $self->{list_ctrl}->InsertColumn( 0, 'Location' ); my $btn = Wx::Button->new( $panel, # parent window -1, # ID 'Add Line', # label [ -1, -1 ], # default position [ -1, -1 ], # default size ); EVT_BUTTON( $self, $btn, sub { $self->add_line($idx); $idx++; } ); my $sizer = Wx::BoxSizer->new(&Wx::wxVERTICAL); $sizer->Add( $self->{list_ctrl}, 0, wxALL | wxEXPAND, 5 ); $sizer->Add( $btn, 0, wxALL | wxCENTER, 5 ); $panel->SetSizer($sizer); return $self; } # end sub new sub add_line { my ( $self, $idx ) = @_; my $line = "Line $idx"; $self->{list_ctrl}->InsertStringItem( $idx, $line ); return; } # end sub add_line package MyApp; use strict; use warnings; use base 'Wx::App'; sub OnInit { my $frame = MyForm->new; $frame->Show(1); } package main; my $app = MyApp->new; $app->MainLoop;

Regards, Stefan

  • Comment on Re: wxPerl fails with a cryptic message: "variable is not of type Wx::Point"
  • Download Code

Replies are listed 'Best First'.
Re^2: wxPerl fails with a cryptic message: "variable is not of type Wx::Point"
by HelenCr (Monk) on Mar 09, 2013 at 09:53 UTC

    Thank you, Stefan, for the thorough answer, and the investment of time and energy. Your post is really helpful. The program, the way you tweaked it, works fine.
    And many thanks to kcott and the other Anonymous Monks who pitched in and responded.

    Following up: Stefan and Monks, I'll be thankful to you if you could help me with the following questions (apologizing beforehand if some of them are quasi-newbie's):

    1. If you examine the Python code example, http://www.blog.pythonlibrary.org/2011/01/04/wxpython-wx-listctrl-tips-and-tricks/, see the lines:
      self.index = 0 self.list_ctrl = wx.ListCtrl(panel, size=(-1,100), style=wx.LC_REPORT |wx.BORDER_SUNKEN )
      Then for self.index = 0 we port it to Perl by declaring a new variable: my $idx =0; So, to port the second line, why not declare a new variable: my $list_ctrl; ?
    2. and what kind of object is $self->{list_ctrl} ? Is it a reference to an anonymous hash? and where is list_ctrl now defined?
    3. When do you use  &Wx::wxLC_SOMETHING, and when just: wxLC_SOMETHING? I notice that you haven't changed it everywhere, but left in some of the subroutine calls?
    4. I notice that you did not include the lines:
      $self->{list_ctrl}->SetStringItem($idx, 1, '01/19/2010'); $self->{list_ctrl}->SetStringItem($idx, 2, 'USA');
      If I do include them, compilation fails with: Can't locate object method "SetStringItem" via package "Wx::Perl::ListCtrl" at Wx List Control test v2.pl line 69.
      How to overcome this? In other words, how do you modify/ insert strings in a ListCTRL line?
    5. Looking ahead, the next necessary step for me, is to "tie" a database table to the Wx List Control, so that when the user scrolls at the GUI window, the application keeps retrieving database table lines (records) and displays them at the window.
      Is there a way to "tie" an RDBMS table to a Wx List Control?

    Thanks again for your thorough help - Helen

      I'm not very good at explaining things, but I'l try, wxLC_xREPORT, wxBORDER_SUNKEN,... are constant integers defined in the Wx package but not imported by default (for example wxLC_xREPORT == 32). After import you can use the short form. If a constant is not imported you can prepend the class name like this: Wx::wxLC_xREPORT. (I'm not sure about the '&').

      I did not change everywhere because it was almost midnight and missed it, no other reason :)

      The sole purpose of the $idx variable is numbering in the label. It uses a closure , see Closure on Closures

      The $list_ctrl variable, in your version of the example, is the reference to the list control object. It is assigned once at the creation of the widget object. This object has methods to add columns and rows to the list, so we need to save it somewhere so we can use it later. One method is to use a hash reference to save it so i can refer to the list object later from other subs.

      Here is how to add data to columns, also using the shortcut form from Anonymous Monk - (thanks!)

      package MyForm; use strict; use warnings; use Wx qw[:everything]; # easy when testing use Wx::Event qw(EVT_BUTTON); use base 'Wx::Frame'; use Wx::Perl::ListCtrl; sub new { my $class = shift; my $self = $class->SUPER::new( undef, # parent window -1, # ID -1 means any 'List Control Tutorial', # title [ -1, -1 ], # default position [ 400, 300 ], # size ); # Add a panel so it looks correct on all platforms my $panel = Wx::Panel->new( $self, # parent window -1, # ID ); my $idx = 0; $self->{list_ctrl} = Wx::Perl::ListCtrl->new( $panel, -1, # ID #'Report', # label [ 20, 30 ], # position [ -1, 100 ], # size wxLC_REPORT | wxBORDER_SUNKEN, # window style ); print " wxLC_REPORT is ", wxLC_REPORT,"\n"; print " wxBORDER_SUNKEN is ", wxBORDER_SUNKEN,"\n"; $self->{list_ctrl}->InsertColumn( 0, 'Subject' ); $self->{list_ctrl}->InsertColumn( 0, 'Due' ); $self->{list_ctrl}->InsertColumn( 0, 'Location' ); my $btn = Wx::Button->new( $panel, # parent window -1, # ID 'Add Line', # label [ -1, -1 ], # default position [ -1, -1 ], # default size ); EVT_BUTTON( $self, $btn, sub { $self->add_line($idx); $idx++; } ); my $sizer = Wx::BoxSizer->new(wxVERTICAL); $sizer->Add( $self->{list_ctrl}, 0, wxALL | wxEXPAND, 5 ); $sizer->Add( $btn, 0, wxALL | wxCENTER, 5 ); $panel->SetSizer($sizer); return $self; } sub add_line { my ($self, $item) = @_; #$item = 0; # unexpected behaviour print " Inserting item $item\n"; my ($col, $text) = (0, 'text'); $self->{list_ctrl}->InsertStringItem( $item, 'dummy' ); $self->{list_ctrl}->SetItemText( $item, $col , "$text.$item.0" ); $self->{list_ctrl}->SetItemText( $item, $col+1, "$text.$item.1" ); $self->{list_ctrl}->SetItemText( $item, $col+2, "$text.$item.2" ); return; } #-- my $app = Wx::SimpleApp->new; my $frame = MyForm->new; $frame->Show(1); $app->MainLoop;

      What is interesting and unespected for me, is that item can be 0 and still adds rows, I was expectig to overwrite the first item.

      Stefan

      Update: Replaced '32' with 'wxLC_REPORT'. I was trying to show that wxLC_REPORT is just a constant, but the result was a wrong example. Also removed 'Wx::' from the other flag.

        Thank you, Stefan. Your post is highly instructive. I'm studying it.

        Many thanks - Helen

      1 .. 2

      yes, self is an object, a hash based object, it a reference to a hash, and yes those references are usually anonymous (outside of the constructor) :)

      index and list_ctrl are attributes of the object -- its object oriented programming -- if they weren't attributes then you couldn't create 20 MyForm's and still have it work, you'd have to create an @index and @list_ctrl -- this is not good for a "Class" ( a module for making object)

      See perlootut, Modern Perl

      When do you use &Wx::wxLC_SOMETHING, and when just: wxLC_SOMETHING?

      Whenever you want :)

      There is a cost to importing constants into a package, and Wx has a lot of them (1mb worth or more), but they all already live in the Wx:: namespace so you can call them Wx::blahblah() and conserve memory -- padre does this, cause 100 subclasses * 1mb = 100mb, not good :)

      OTOH, I suppose the same memory saving effect could be accomplished with less typing with use namespace::clean;

      In any case, whether you type it, or you use a oneliner to fixup your constants, or use WxEXPORTS to cherrypick your exports, or whatever, do what hurts the least and fits your process

      Can't locate object method "SetStringItem" ... How to overcome this

      Read what you're reading closer, read the actual documentation, http://docs.wxwidgets.org/2.8/wx_wxlistctrl.html#wxlistctrlsetitem

      wxPython note: In place of a single overloaded method name, wxPython implements the following methods: SetItem(item) Sets information about the given wxListItem. SetStringItem(index, col, label, imageId) Sets a string or image at a given location.

      So taking a page out of my tutorial

      $ perl -MWx -le " Wx::ListCtrl->new->SetItem" unable to resolve overloaded method for Wx::ListCtrl::SetItem at -e li +ne 1. $ perl -MWx -le " Wx::ListCtrl->new->SetItem( 1 .. 10 )" Usage: Wx::ListCtrl::SetItemString(THIS, index, col, label, image = -1 +) at -e line 1.

      Is there a way to "tie" an RDBMS table to a Wx List Control?

      Yes, its called programming :P

        Is there a way to "tie" an RDBMS table to a Wx List Control?
        Yes, its called programming :P

        I don't like it when stuff isn't on CPAN :) breaks the easy searches :) Wx::DBI, Wx::DBI::Form::Tree - a database aware tree

        Doesn't seem to have more than one user, but it could be workable

        update: or examples of use or a test suite

        Its still possible its workable, the some of the docs show methods, but I it leans towards no -- crafting an example would be work :)

Re^2: wxPerl fails with a cryptic message: "variable is not of type Wx::Point"
by Anonymous Monk on Mar 09, 2013 at 00:29 UTC

    You could even write

    my $app = Wx::SimpleApp->new; my $frame = MyForm->new; $frame->Show(1); $app->MainLoop;
    skips the extra subclassing :)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://1022500]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others browsing the Monastery: (7)
As of 2024-04-24 11:14 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found