|
Problem This is in response to Peter's post titled "The opposite to GtkTable::attach()".
He would like to be able to unattach a cell content and replace the cell with some other widgets.
In particular, he has an original widget that spans from columns 14 to 20. He wants to replace this widget with one that spans columns 15 and 16 and a second one that spans columns 18-20. column 17 is to remain empty.
In this Part 1, I will first show you how to replace a single cell widget with another single cell widget. We will deal specifically with Peter's case in Part 2.
When you first run the sample code, each cell of the GtkTable contains a GtkLabel.

When you click the button "Remove first two rows", the GtkLabel's of all the cells in the first two rows will be removed as shown below:

When you click the button "Replace first two rows", the GtkLabel's of all the cells in the first two rows will be replaced with GtkEtnry's as shown below:

Solution
- For one reason or another, GtkTable DOES NOT provide an unattach() method.
- In this example, note that there is no spanning of widgets across different rows or columns. So what I've done is to attach a GtkVBox to each and every single cell in the table. Each GtkLabel is then packed into the GtkVbox.
- When you need to replace the GtkLabel with GtkEntry, you first make use of the method GtkContainer::remove() to empty all the widgets in each GtkVBox. Now that the GtkVBox is empty, you create a new GtkEntry and pack it into the GtkVBox.
Sample Code 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 90 91 92 93 94
| <?php $window = new GtkWindow(); $window->set_size_request(400, 200); $window->connect_simple('destroy', array('Gtk','main_quit')); $window->add($vbox = new GtkVBox());
// display title
$title = new GtkLabel(" How to unattach a widget from GtkTable\n". "or replace a GtkTable cell with another widget"); $title->modify_font(new PangoFontDescription("Times New Roman Italic 10")); $title->modify_fg(Gtk::STATE_NORMAL, GdkColor::parse("#0000ff")); $title->set_size_request(-1, 40); $vbox->pack_start($title, 0, 0); $vbox->pack_start(new GtkLabel(), 0, 0);
$table = new GtkTable(); // note 1
$item[0][0] = new GtkVBox(); // note 2
$item[0][0]->pack_start(new GTkLabel('item 0-0')); // note 3
$table->attach($item[0][0], 0, 1, 0, 1); // note 4
$item[0][1] = new GtkVBox(); // note 5
$item[0][1]->pack_start(new GTkLabel('item 0-1')); // note 5
$table->attach($item[0][1], 1, 2, 0, 1); // note 5
$item[0][2] = new GtkVBox(); $item[0][2]->pack_start(new GTkLabel('item 0-2')); $table->attach($item[0][2], 2, 3, 0, 1);
$item[1][0] = new GtkVBox(); $item[1][0]->pack_start(new GTkLabel('item 1-0')); $table->attach($item[1][0], 0, 1, 1, 2);
$item[1][1] = new GtkVBox(); $item[1][1]->pack_start(new GTkLabel('item 1-1')); $table->attach($item[1][1], 1, 2, 1, 2);
$item[1][2] = new GtkVBox(); $item[1][2]->pack_start(new GTkLabel('item 1-2')); $table->attach($item[1][2], 2, 3, 1, 2);
$item[2][0] = new GtkVBox(); $item[2][0]->pack_start(new GTkLabel('item 2-0')); $table->attach($item[2][0], 0, 1, 2, 3);
$item[2][1] = new GtkVBox(); $item[2][1]->pack_start(new GTkLabel('item 2-1')); $table->attach($item[2][1], 1, 2, 2, 3);
$item[2][2] = new GtkVBox(); $item[2][2]->pack_start(new GTkLabel('item 2-2')); $table->attach($item[2][2], 2, 3, 2, 3);
$vbox->pack_start($hbox = new GtkHBox(), 0); $hbox->pack_start($button1 = new GtkButton('Remove first two rows'), 0); $button1->connect('clicked', 'remove_first_two_rows', $item); $hbox->pack_start($button2 = new GtkButton('Replace first two rows'), 0); $button2->connect('clicked', 'replace_first_two_rows', $item);
$vbox->pack_start($table);
$window->show_all(); Gtk::main();
function remove_first_two_rows($button, $item) { remove_widgets($item[0][0]); remove_widgets($item[0][1]); remove_widgets($item[0][2]); remove_widgets($item[1][0]); remove_widgets($item[1][1]); remove_widgets($item[1][2]); }
function replace_first_two_rows($button, $item) { remove_first_two_rows($button, $item); $item[0][0]->pack_start(new GtkEntry('new item 0-0'), 0); // note 7
$item[0][1]->pack_start(new GtkEntry('new item 0-1'), 0); $item[0][2]->pack_start(new GtkEntry('new item 0-2'), 0); $item[1][0]->pack_start(new GtkEntry('new item 1-0'), 0); $item[1][1]->pack_start(new GtkEntry('new item 1-1'), 0); $item[1][2]->pack_start(new GtkEntry('new item 1-2'), 0);
global $table; $table->show_all(); }
function remove_widgets($container) { foreach($container->get_children() as $widget) { // note 6
$container->remove($widget); // note 6
} }
?>
|
Explanation Note that I've purposely manually created each cell so that it's easy for you to understand. Once you understand the rationale, you can proceed to optimize the code with some for loops.
- Create a new table.
- For each cell, create a new GtkVBox.
- Create a new GtkLabel and pack it into the vbox.
- Attach the GtkVBox to the cell.
- Repeat 2 to 4 for all other cells.
- Remove all widgets within the GtkVBox.
- Pack a new GtkEntry in the GtkVBox.
Related Links
User reviews There are no user reviews yet. Note: You have to be a registered member to leave a comment. Free registration here. |