Re: Converting from Gtk2 -> Gtk3 Notes

Epic post :) I've tried a number of times to port my code from Gtk2 to Gtk3. Some of these tips might help me complete it next time.


On Tue, Sep 24, 2013 at 9:08 AM, Terence Ferraro <terencejferraro gmail com> wrote:
I have included below various changes, gotchas, and general notes I accrued in converting our application from perl Gtk2 to perl Gtk3.

Near the bottom, you'll also notice some changes I made directly to I suppose I could have created a diff as these changes were made to produce backward-compatible functionality but, they essentially break the "new" Gtk3 style for those widgets. However, if anyone else needs to convert a major project over, these changes will shave a *lot* of time off of said conversion.

Also, these notes are current as of 0.09 (which is no longer the latest version).


Was: $dialog->vbox->add($grid);
Now: $dialog->get_content_area->pack_start($grid,1,1,0);

Was: $widget->isa(Gtk2::Window)
Now: ? (Started calling $widget->get_toplevel for similar functionality with respect to our system)

Was: ComboBoxEntry
Now: ComboBox

Was: ComboBoxEntry->new($store,0);
Now: ComboBox->new_with_model_and_entry($store); $combo->set_entry_text_column(0);

Was: ComboBoxEntry->get_child;
Now: Gtk3::Bin::get_child($combo)

Was: $combo->get_active_text;
Now: Gtk3::Bin::get_child($combo)->get_text;

Was: my $loader = Gtk2::Gdk::PixbufLoader->new; $loader->write($img);
Now: my $loader = Gtk3::Gdk::PixbufLoader->new; $loader->write([unpack 'C*', $imgdata]);
(Thanks Khisanth)

Was: Gtk2::Image could be attached to a grid
Now: Gtk3::Image add to a event box, then attach box to grid

Was: Gtk2::RadioButton->new
Now: Gtk3::RadioButton->new_with_label

Was: Gtk2::CheckButton->new
Now: Gtk3::CheckButton->new_with_label

Was: $group = $radio->get_group; $radio1 = Gtk2::RadioButton->new($group,'Label');
Now: $radio1 = Gtk2::RadioButton->new($radio,'Label');

Was: Gtk3->main_iteration while Gtk3->events_pending;
Now: Gtk3::main_iteration while Gtk3::events_pending;

Progressbar must have show-text for text to appear now: $progressbar->set_property('show-text' => 1);

Can't use: $store->get_value($iter,0,1,2,3,4);
Must use: $store->get($iter,0,1,2,3,4);

Can't use: $store->set_value
Must use: $store->set

Lazy loading gtk3 doesn't seem to work, can't use "require", must use "use"

Both Frame and Labels must be passed a blank string '' instead of no value

Can't use $button->set_image(undef) needs to be $button0->set_image(Gtk3::Image::new);

drag_source_set and drag_dest_set used to require a target_table array defined purely in perl. Also, the argument order has changed slightly. Used to be: $widget->drag_source_set(['button1_mask', 'button3_mask'], ['copy', 'move'], @targets); Now, requires an array of Gtk3::TargetEntry and must be called as such:
$widget->drag_source_set (['button1_mask', 'button3_mask'], \ main::target_table, ['copy','move']);
$widget->drag_dest_set('all', \ main::target_table, ['copy', 'move']);

my $oldcolor = $widget->get_style->bg('normal'); had to replaced with:
sub getbackgroundcolorfrombutton
    my ($button) = @_;
    my $style = $button->get_style;
    my $stylecontext = $style->get_property('context');
    my $bgcolor = $stylecontext->get_property('background-color','normal');
    my $bgstring = $bgcolor->to_string;
    my @a = split(/\(/, $bgstring);
    my @b = split(/,/, $a[1]);
    my $>     my $two = uc(sprintf("%x",$b[1]));
    my $three = uc(sprintf("%x",$b[2]));
    if(length($one) == 1) { $ . $one; }
    if(length($two) == 1) { $two = '0' . $two; }
    if(length($three) == 1) { $three = '0' . $three; }
    my $oldcolor = [Gtk3::Gdk::Color::parse('#' . $one . $two . $three)]->[1];

$button->set_always_show_image(1); should be called if set_image and set_label are both used. This was not necessary in Gtk2.

need to replace all instances of Gtk3::Gdk::Color::parse('#EEEEEE') with [Gtk3::Gdk::Color::parse('#EEEEEE')]->[1]

Applied icon-size-support-v0.patch

Gtk2::Rc->parse($themedata) should be replaced with new theming engine css stuff:
    my $provider = Gtk3::CssProvider->new();
    my $display = Gtk3::Gdk::Display::get_default;
    my $screen = Gtk3::Gdk::Display::get_default_screen($display);
drawingarea->window is now drawingarea->get_window()

drawingarea->visible is now drawingarea->get_visible()

For size-allocation signal, is no longer: $rectangle->height,$rectangle->width is: $rectangle->{'height'},$rectangle->{'width'}

Allocation can no longer be pulled as $draw->allocation. Is now: my $allocation = Gtk3::Widget::get_allocation($docdraw); Must then be referenced as a hash as noted above

No longer connect to on_expose_event, connect to draw

Instead of Gtk2::Gdk::Cairo::Context::set_source_pixbuf($cairocontext,0,0) should not be dealing with pixbuf anymore when rendering, instead take png images and convert to image surfaces:
    my $fh = new IO::Scalar \$png;
    my $tempsurface = Cairo::ImageSurface->create_from_png_stream(sub { my ($fh, $length) = @_; my $tempdata; my $nread = sysread($fh,$tempdata,$length) or print "Couldn't read\n"; return($tempdata); },$fh);

$treeview->set_cursor($path) should now be $treeview->set_cursor($path,undef,0);

No longer: Gtk3::Entry->new_with_max_length (2); Now: Gtk3::Entry->new(); $entry->set_max_length(2);

my $keyval = "Gtk3::Gdk::KEY_$char"; my $key = eval($keyval);

Before: $complete->signal_connect(match_selected => sub { $combo->set_active_iter($_[1]->convert_iter_to_child_iter($_[2])); });
Now: $complete->signal_connect(match_selected => sub { $combo->set_active_iter($_[2]); });

Below are some changes I made to the core for compatibility reasons.

my @selection = $main::plantinventorytree->get_selection->get_selected_rows; now returns a two-dimensional array instead of one. Overridden:
sub Gtk3::TreeSelection::get_selected_rows
    my ($treeselection) = @_;
    my ($ref,$model) = Glib::Object::Introspection->invoke (
    $_GTK_BASENAME, 'TreeSelection', 'get_selected_rows', $treeselection);
    if(defined($ref) && length($ref->[0]) > 0) { return(@$ref); }
    my @a;

Modified to include the following in both: Gtk3::TreeStore::insert_with_values and Gtk3::ListStore::insert_with_values
if(length($position) == 0) { $position = 0; }

Modified to include the following override method as to not break 90% of my program:
sub Gtk3::Entry::set_text {
if(!defined($_[1])) { $_[1] = ''; }
  return Glib::Object::Introspection->invoke (
    $_GTK_BASENAME, 'Entry', 'set_text',($_[0],$_[1]));

Added the following override due to random breakage returning valid (unintialized) iters causing all sorts of issues with previous assuming definedness was a valid check
sub Gtk3::ComboBox::get_active_iter
    my ($combo) = @_;
    my ($bool,$iter) = Glib::Object::Introspection->invoke (
    $_GTK_BASENAME, 'ComboBox', 'get_active_iter', $combo);

    if($bool == 1) { return($iter); }
    else { return(undef); }

sub Gtk3::Frame::new {
    my $frame = Glib::Object::Introspection->invoke ( $_GTK_BASENAME, 'Frame', 'new', ('',''));

sub Gtk3::TextBuffer::set_text {
if(!defined($_[1])) { $_[1] = ''; }
  return Glib::Object::Introspection->invoke (
    $_GTK_BASENAME, 'TextBuffer', 'set_text',
    @_ == 3 ? @_ : (@_[0,1], -1)); # wants length in bytes

Can't use: for($iter = $store->get_iter_first;$iter;$iter =  $store->iter_next($iter))
Tried using this initially: my $valid = 1; for($iter = $store->get_iter_first;$valid;$valid = $store->iter_next($iter))
However, direct modification of iters *severely* broke a ton of code, so added this to

sub Gtk3::TreeModel::iter_next
    my ($model,$iter) = @_;
    my $newiter = $iter->copy;
    my $bool = Glib::Object::Introspection->invoke (
      $_GTK_BASENAME, 'TreeModel', 'iter_next', $model,$newiter);
    if($bool == 1) { return($newiter); }
    else { return(undef); }

gtk-perl-list mailing list
gtk-perl-list gnome org

[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]