http://www.perlmonks.org?node_id=1022548


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

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

Replies are listed 'Best First'.
Re^3: wxPerl fails with a cryptic message: "variable is not of type Wx::Point"
by stefbv (Curate) on Mar 09, 2013 at 12:10 UTC

    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

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

    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 :)