james28909 has asked for the wisdom of the Perl Monks concerning the following question:

i have successfully figured out how to append strings to a listbox from a variable, now the problem is formatting the text. i can change the font size, face, ect but i cannot figure out how to color the text green or red, is there a package i am missing?

Here is the code, and i just want the if statement to color green if true and red if false.
use File::Slurp; use Digest::MD5; use Wx; use Wx qw(:everything); use Wx::Event qw(EVT_DROP_FILES); use Wx::DND qw(FileDropTarget); ###################################################################### +######## my $app = Wx::SimpleApp->new; my $frame = Wx::Frame->new( undef, -1, 'test tool', [150,600], Wx::Size->new(700,400), wxDEFAULT_DIALOG_STYLE|wxSTAY_ON_TOP ); ###################################################################### +######### tool($frame); sub tool { my ($self) = @_; $frame->DragAcceptFiles(1); EVT_DROP_FILES( $frame, \&ondrop ); sub ondrop { my ($self, $this) = @_; $lb->Clear(); Wx::DropFilesEvent::GetFiles($this); our $dropfile = $this->GetFiles(); \&file($dropfile); } my $noteBook = Wx::Notebook->new($frame, -1, wxDefaultPosition, wx +DefaultSize); my $window1 = Wx::Panel->new($noteBook, wxID_ANY); my $window2 = Wx::Panel->new($noteBook, wxID_ANY); my $window3 = Wx::Panel->new($noteBook, wxID_ANY); $noteBook->AddPage($window1, "First", 1, 0); $noteBook->AddPage($window2, "Second", 0, 1); $noteBook->AddPage($window3, "Third", 0, 2); our $lb = $window1->{my_listbox} = Wx::ListBox->new($window1, wxID_ANY, [350 , 10] +, Wx::Size-> +new(300,330 )); sub file { my $dirname = "extracted/"; my @md5s = read_file("md5"); my $md5s = join( '', @md5s ); my $filesize = ''; open( my $buf1, '<', "extracted/sdk_version" ) or die "cannot open sdk +_version: $!"; seek( $buf1, 0x00, 0 ); read( $buf1, my $sdk, 0x03 ); foreach my $file (<$dirname/*>) { next if -d $file; open( my $FILE, $file ); binmode($FILE); $filesize = -s $FILE; $file =~ s{.*/}{}; $md5 = Digest::MD5->new->addfile($FILE)->hexdigest; if ( $md5s =~ $md5 ) { $lb->SetFont( Wx::Font->new( 7, wxDEFAULT, wxNORMAL, wxBOLD, # would like to set color somewhere in these properties 0, "Comic Sans MS" ) ); $lb->Append(" Match! | $sdk | $file | $filesize"); } else { $lb->SetFont( Wx::Font->new( 7, wxDEFAULT, wxNORMAL, wxBOLD, # would like to set color somewhere in these properties 0, "Comic Sans MS" ) ); $lb->Append(" Warning! | $sdk | $file | $filesize"); } } } } $frame->Show(1); $app->SetTopWindow($frame); $app->MainLoop;


in the code above, it opens a window and when you drop a file on it, it runs it thru the "sub file". this sub is setup to open a directory and get md5 of everyfile in that directory, then open an exsisting md5 file and store it in array, then join the array into "$md5s". after that it also gets the filename ($file =~ s{.*/}{};) and get filesize ($filesize = -s $FILE;). after that, it compares the output of the "$md5" from each file in the directory against the stored "$md5s".
if the $md5 from the files matches the md5s thats stored in $md5s, it will return true and append "" Match! | $sdk | $file | $filesize" to the listbox. if it returns false, it will append "" Warning! | $sdk | $file | $filesize". This is where i want to make the text red or green. if it returns true, i would like the text to be green, if it returns false i would like it to be red.

Replies are listed 'Best First'.
Re: oh wise monks, i beseech thee
by boftx (Deacon) on Jul 11, 2014 at 04:10 UTC

    It is wise to come to the Monastery to seek wisdom. But true wisdom begins when one beseeches wisely.

    You must always remember that the primary goal is to drain the swamp even when you are hip-deep in alligators.
      original post updated :) thanks in advance for any info
      sorry bout that, ill post some code and explain better :)
        *ahem*:) Select an informative title. :)
      well i can get the list green or red. i dont know if this is what i want either. because i want there is be one column, and the string that gets added needs to be red or green foreach $md5. as it stands right now, i can only make the whole kist green if first match is true, or it makes the whole list red if first statement is false :( hopefully i can figure this out because after this is done, i just got to format the look of the gui as i see fit, then it will be done and i can move on to something else :P

      do you think listview would be better? ill try that
        Just read the example and run the example and you'll see :)
Re: How do i color font in a listbox?
by zentara (Cardinal) on Jul 11, 2014 at 09:44 UTC
    You my friend, are about to be introduced to the wonderful world of css in conventional apps.

    As one of the benefits to using of the newer toolkits, and since Wx is usually built on Gtk+ libs, you now get to wrack-your brain trying to figure out how to override the internal themeing engine, and it isn't a cake-walk. Now, in Tk all you need to do is set a -fg option or a -bg option for the inserts. But in the newer toolkits, like Wx, you will need to find out how to override the default theme, either in the .gtk2rc or .config/gtk3 files.

    The solution all depends on which version of Wx that you have going. Are you using one based on Gtk2 or Gtk3? In the latest, you will need to setup a Gtk3::CssProvider->new; ; which of course is named something different (but similar) in Wx.

    This will allow you to override a theme, so google for Wx CSSProvider and hope you find a solution.

    If you want an easier solution, IMHO, rather than jump thru hoops to get custom colors in a listbox, why not put your data into a Text Widget, which lets you tag inserts with colors.


    I'm not really a human, but I play one on earth.
    Old Perl Programmer Haiku ................... flash japh
        I can't believe how complicated this all has become. I'm glad to hear WxWidgets is making progress toward making setting a bg and fg color easier.

        I'm not really a human, but I play one on earth.
        Old Perl Programmer Haiku ................... flash japh
Re: How do i color font in a listbox?
by Anonymous Monk on Jul 11, 2014 at 07:32 UTC
      yeah i seen ListCtrl in the docs, but i didnt know if it was just something easy i was missing in Listbox like
      $md5->SetFontColor(wxRED);
      lol
      seems like i tried something like the above and it complained about not having a package or something. ill try to reproduce the error. anyway, i will switch to listctrl,i think it will be better to use in the long run anyway because i can set each variable into its own named column which will keep everything uniform and easy to read

      thanks again.
      oh and the nested subs you are talking about is, how sub onDrop and sub file is inside of sub tool?
Re: How do i color font in a listbox?
by james28909 (Deacon) on Aug 03, 2014 at 05:35 UTC
    i have found alot better of a way to accomplish what i was after, works great and i can format its output to my liking :) sorry for being such a pain @anonymous monk :p
    my ($red, $green) = ( Wx::Colour->newRGB(235, 0, 0), Wx::Colour->newRGB(0, 110, 63) ); @md5s = ""; $md5s = ""; $filesize = ''; @md5s = read_file("md5"); $md5s = join( '', @md5s ); my $dirname1 = "some/path/to/files/with/known/md5s"; foreach my $file (<'$dirname1'/*>) { next if -d $file; open( my $FILE, $file ); binmode($FILE); $filesize = -s $file; $file =~ s{.*/}{}; $md5 = Digest::MD5->new->addfile($FILE)->hexdigest; if ( $md5s =~ $md5 ) { my $style1 = Wx::TextAttr->new(); $style->Wx::TextAttr::SetTextColour($green); $lc->SetStyle(-1,-1,$style1); $lc->AppendText("$file | $filesize\n"); } else { my $style2 = Wx::TextAttr->new(); $style1->Wx::TextAttr::SetTextColour($red); $lc->SetStyle(-1,-1,$style2); $lc->AppendText("$file | $filesize\n"); open( my $temporary, '>>', "$dir/md5.txt" ); for ($md5s) { syswrite( $temporary, "$md5\n" ); } } }
    So in the end, it was TextCtrl that worked for what i needed. this will get md5 of each file in a directory, compare it against known md5s in a file (@md5s) if it matches text will be green, else it will be red. I really hope this helps someone in the future.
Re: How do i color font in a listbox?
by james28909 (Deacon) on Jul 24, 2014 at 16:14 UTC
    I Have Figured it out lol. anybody who reads this in the future, use listctrl ;)...

    $dirname = "$dir/path/"; $lc->DeleteAllItems(); my ($red, $green) = ( wxRED, wxGREEN ); foreach my $file ( <'$dirname'/*> ) { next if -d $file; open( my $FILE, $file ); binmode( $FILE ); $filesize = -s $file; $file =~ s{.*/}{}; $md5 = Digest::MD5->new->addfile($FILE)->hexdigest; if ( $md5s =~ $md5 ) { my $text = ( "Match! | $file | $filesize\n" ); $lc->InsertStringItem( 0, $text ); ( $text ) = Wx::ListItem->new; $text->SetId( 0 ); $text->SetTextColour( $green ); $lc->SetItem( $text ); } else { my $text = ( "Warning! | $file | $filesize\n" ); $lc->InsertStringItem( 0, $text ); ( $text ) = Wx::ListItem->new; $text->SetId( 0 ); $text->SetTextColour( $red ); $lc->SetItem( $text ); } }

    this will color each individual item in a listctrl. im not sure if this is the "proper" way to do it but it does work. now i just need to specify a darker shade of green, cz that bright green is like glow in the dark.
Re: How do i color font in a listbox?
by james28909 (Deacon) on Jul 25, 2014 at 23:56 UTC
    i for got to say this too, you can also specify the exact color you want with something like:
    my ( $customsolor1, $customcolor2 ) = ( Wx::Colour->newRGB(255, 255, 25 +5); Wx::Colour->newRBG(0, 100, 0) );

    and like i said, i dont know if this is the proper way to do it, but it does work :p
Re: How do i color font in a listbox?
by james28909 (Deacon) on Jul 26, 2014 at 18:06 UTC
    i have ran into a problem/brick wall.

    when i add wxLC_SORT_ASCENDING, only the first entry is colored and the rest are black. i dont know why the listctrl is auto populated backwards,maybe its a windows only issue, but it requires wxLC_SORT_ASCENDING to display the items from a-z instead of z-a, which terminates colored items after the first entry. if anyone is still reading this, what could be a work around for this?