wxTreeCtrl always shows selected item as focused, on GTK2 and GTK3 - gtk

I'm running Kubuntu 18.04 with the Breeze theme selected for both GTK2 and GTK3. Running the 'treectrl' program from the 'examples' directory on the source distribution creates the window shown below:
The window has a wxTreeCtrl with some items and a text control showing a log. If I click on an item on the tree it's background turns blue, indicating both selection and focus on the wxTreeCtrl. If I them click on the text control the caret appears, indicating that the text control has taken the focus but the selected item on the tree remains with a blue background.
Other (pretty much all other) controls change the background colour of the selection to a different colour to indicate selection without focus.
Why doesn't wxTreeCtrl follow this and can it be reverted back to the normal behaviour?
------ Edit -------
I've build a native GTK3 app using the code :
#include <gtk/gtk.h>
enum {
COLUMN = 0,
NUM_COLS
};
GtkTreeModel *create_and_fill_model(void) {
GtkTreeStore *treestore;
GtkTreeIter toplevel, child;
treestore = gtk_tree_store_new(NUM_COLS,
G_TYPE_STRING);
gtk_tree_store_append(treestore, &toplevel, NULL);
gtk_tree_store_set(treestore, &toplevel,
COLUMN, "Scripting languages",
-1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child,
COLUMN, "Python",
-1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child,
COLUMN, "Perl",
-1);
gtk_tree_store_append(treestore, &child, &toplevel);
gtk_tree_store_set(treestore, &child,
COLUMN, "PHP",
-1);
return GTK_TREE_MODEL(treestore);
}
GtkWidget *create_view_and_model(void) {
GtkTreeViewColumn *col;
GtkCellRenderer *renderer;
GtkWidget *view;
GtkTreeModel *model;
view = gtk_tree_view_new();
col = gtk_tree_view_column_new();
gtk_tree_view_column_set_title(col, "Programming languages");
gtk_tree_view_append_column(GTK_TREE_VIEW(view), col);
renderer = gtk_cell_renderer_text_new();
gtk_tree_view_column_pack_start(col, renderer, TRUE);
gtk_tree_view_column_add_attribute(col, renderer,
"text", COLUMN);
model = create_and_fill_model();
gtk_tree_view_set_model(GTK_TREE_VIEW(view), model);
g_object_unref(model);
return view;
}
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *view;
GtkTreeSelection *selection;
GtkWidget *vbox;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(window), "Tree view");
gtk_widget_set_size_request(window, 350, 300);
vbox = gtk_vbox_new(FALSE, 2);
gtk_container_add(GTK_CONTAINER(window), vbox);
view = create_view_and_model();
selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(view));
gtk_box_pack_start(GTK_BOX(vbox), view, TRUE, TRUE, 1);
GtkWidget *entry = gtk_entry_new();
gtk_box_pack_start(GTK_BOX(vbox), entry, TRUE, TRUE, 1);
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
that shows a window with a Tree View control on top and a Entry control on bottom. The behaviour is the same, as seen in the picture:

Related

Alternative to deprecated gtk_alignment_new

I used the GtkAlignment widget to control the alignment and size of its child widget. But gtk_alignment_new has been deprecated since version 3.14 and should not be used in newly-written code. What functions should I use as alternatives to let the code be gtk3+ compatible?
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;
GtkWidget *halign;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Tooltip");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_container_set_border_width(GTK_CONTAINER(window), 15);
button = gtk_button_new_with_label("Button");
gtk_widget_set_tooltip_text(button, "Button widget");
halign = gtk_alignment_new(0, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(halign), button);
gtk_container_add(GTK_CONTAINER(window), halign);
gtk_widget_show_all(window);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_main();
return 0;
}
As suggested in the comment, use these two functions instead:
void gtk_widget_set_halign (GtkWidget *widget, GtkAlign align);
Sets the horizontal alignment of widget.
gtk_widget_get_valign (GtkWidget *widget); Sets the vertical alignment of widget.
The enum GtkAlign types are the following:
GTK_ALIGN_START: The 'start' of the layout. Vertically this is the top, horizontally this is left/right according to LTR/RTL
GTK_ALIGN_END: Opposite of GTK_ALIGN_START
GTK_ALIGN_CENTER: The middle of the layout
GTK_ALIGN_FILL : Take all available space
for scaling use GTK_ALIGN_FILL.
So the gtk3+ compatible alternative for your code is the following:
#include <gtk/gtk.h>
int main(int argc, char *argv[]) {
GtkWidget *window;
GtkWidget *button;
gtk_init(&argc, &argv);
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Tooltip");
gtk_window_set_default_size(GTK_WINDOW(window), 300, 200);
gtk_container_set_border_width(GTK_CONTAINER(window), 15);
button = gtk_button_new_with_label("Button");
gtk_widget_set_tooltip_text(button, "Button widget");
gtk_widget_set_halign (button, GTK_ALIGN_START);
gtk_widget_set_valign (button, GTK_ALIGN_START);
gtk_container_add (GTK_CONTAINER (window), button);
g_signal_connect(G_OBJECT(window), "destroy",
G_CALLBACK(gtk_main_quit), NULL);
gtk_widget_show_all(window);
gtk_main();
return 0;
}

GtkNotebook does not show tab label content

In an application with a GtkNotebook and a GtkBox as tab label, the tab label is visible, but the content of the tab label is not. How can I make the content of the tab label visible?
#include <gtk/gtk.h>
int main (int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* notebook = gtk_notebook_new();
GtkWidget* page_content = gtk_label_new("Content");
GtkWidget* tab_label = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* label_content_1 = gtk_label_new("Title");
GtkWidget* label_content_2 = gtk_button_new_with_label("Close");
gtk_box_pack_start(GTK_BOX(tab_label), label_content_1, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(tab_label), label_content_2, FALSE, FALSE, 0);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_content, tab_label);
gtk_container_add(GTK_CONTAINER(window), notebook);
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main();
}
I got it working by showing the widgets in GTK_BOX explicitly, and calling gtk_notebook_set_show_tabs:
#include <gtk-3.0/gtk/gtk.h>
int main (int argc, char *argv[])
{
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
GtkWidget* notebook = gtk_notebook_new();
GtkWidget* page_content = gtk_label_new("Content");
GtkWidget* tab_label = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget* label_content_1 = gtk_label_new("Title");
GtkWidget* label_content_2 = gtk_button_new_with_label("Close");
gtk_widget_show(GTK_WIDGET(label_content_1));
gtk_widget_show(GTK_WIDGET(label_content_2));
gtk_widget_show(GTK_WIDGET(tab_label));
gtk_box_pack_start(GTK_BOX(tab_label), label_content_1, TRUE, TRUE, 0);
gtk_box_pack_end(GTK_BOX(tab_label), label_content_2, FALSE, FALSE, 0);
gtk_notebook_append_page(GTK_NOTEBOOK(notebook), page_content, tab_label);
gtk_notebook_set_show_tabs(GTK_NOTEBOOK(notebook), TRUE);
gtk_container_add(GTK_CONTAINER(window), notebook);
gtk_widget_show_all(GTK_WIDGET(window));
gtk_main();
}
I am not in a position to explain the reason behind that though.
You may find this link about tabs with close button interesting.

using GtkAlignment for horizontal alignment

I am new to GTK+ world and trying to learn it from Foundations of GTK+ Development.
Mean while I am getting some problem in using GtkAlignment widget, as in the code below.
Even if I change the value of either one of the below I am not getting the Ok and calcel button getting aligned to right.
GtkWidget* halign = gtk_alignment_new(0, 0, 0, 0);
GtkWidget* halign = gtk_alignment_new(0, 1, 0, 0);
I think I'm missing something, but not getting exactly
Note: I am using GTK+3 on windows 7
int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Gtk Alignment Sample");
gtk_container_set_border_width(GTK_CONTAINER(window), 5);
gtk_widget_set_size_request(window, 250, 400);
g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
GtkWidget* ok_button = gtk_button_new_from_stock(GTK_STOCK_OK);
GtkWidget* cancel_button = gtk_button_new_from_stock(GTK_STOCK_CANCEL);
GtkWidget* hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
gtk_box_pack_start(GTK_BOX(hbox), ok_button, FALSE, FALSE, 0);
gtk_box_pack_start(GTK_BOX(hbox), cancel_button, FALSE, FALSE, 0);
GtkWidget* halign = gtk_alignment_new(0, 0, 0, 0);
gtk_container_add(GTK_CONTAINER(halign), hbox);
GtkWidget* vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
gtk_box_pack_start(GTK_BOX(vbox), halign, FALSE, FALSE, 0);
GtkWidget* valign = gtk_alignment_new(0, 1, 0, 0);
gtk_container_add(GTK_CONTAINER(valign), vbox);
gtk_container_add(GTK_CONTAINER(window), valign);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Quote from the docs:
Note that the desired effect can in most cases be achieved by using
the "halign", "valign" and "margin" properties on the child widget, so
GtkAlignment should not be used in new code.
Try to just use
gtk_widget_set_alignment (button_ok, GTK_ALIGN_END);
gtk_widget_set_alignment (button_cancel, GTK_ALIGN_END);
//or
gtk_widget_set_alignment (hbox, GTK_ALIGN_END);
and remove all alignment widgets

stopping buttons in hbox to expand vertically

In gtk+3.0 in windows 7.
I am creating a button and packed them into horizontal box. I have set the expand to FALSE. Now the button is not expanding in x direction but expanding vertically. I don't want the button to expand vertically also.
int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
GtkWidget* window = NULL;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Layout using BOX");
//gtk_widget_set_size_request(window, 50, 300);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
GtkWidget* button[5] = {NULL};
for(int i = 0; i < 5; ++i) {
std::stringstream buton_label;
buton_label << "Button ";
buton_label << (i + 1);
button[i] = gtk_button_new_with_label(buton_label.str().c_str());
gtk_widget_set_hexpand(button[i], FALSE);
g_signal_connect(button[i], "clicked", G_CALLBACK(button_clicked_cb), (gpointer)window);
}
GtkWidget *hbox = NULL;
hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
//hbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
for(int i = 0; i < 5; ++i) {
gtk_box_pack_start(GTK_BOX(hbox), button[i], FALSE, TRUE, 10);
}
gtk_container_add(GTK_CONTAINER(window), hbox);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
In GTK 3, the widget tells the container how it wants to be expanded (was the opposite in GTK 2). So you need to use the hexpand and vexpand properties of your widget for horizontal and vertical expanding, with functions like gtk_widget_set_hexpand. Same for alignment with halign and valign.
EDIT:
As an exception to the rule, read the documentation of gtk_box_pack_start and its fill parameter:
fill
TRUE if space given to child by the expand option is actually
allocated to child , rather than just padding it. This parameter has
no effect if expand is set to FALSE. A child is always allocated the
full height of a horizontal GtkBox and the full width of a vertical
GtkBox. This option affects the other dimension.
So if you want to control the other dimension, put the horizontal box inside a vertical box where you'll set expand to FALSE when calling gtk_box_pack_start.
#include <gtk/gtk.h>
#include <sstream>
int main(int argc, char* argv[]) {
gtk_init(&argc, &argv);
GtkWidget* window = NULL;
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(window), "Layout using BOX");
//gtk_widget_set_size_request(window, 50, 300);
gtk_container_set_border_width(GTK_CONTAINER(window), 10);
g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
GtkWidget* button[5] = {NULL};
for(int i = 0; i < 5; ++i) {
std::stringstream buton_label;
buton_label << "Button ";
buton_label << (i + 1);
button[i] = gtk_button_new_with_label(buton_label.str().c_str());
gtk_widget_set_hexpand(button[i], FALSE);
// g_signal_connect(button[i], "clicked", G_CALLBACK(button_clicked_cb), (gpointer)window);
}
GtkWidget *hbox = gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 0);
GtkWidget *vbox = gtk_box_new(GTK_ORIENTATION_VERTICAL, 0);
for(int i = 0; i < 5; ++i) {
gtk_box_pack_start(GTK_BOX(hbox), button[i], FALSE, FALSE, 10);
}
gtk_container_add(GTK_CONTAINER(vbox), hbox);
gtk_container_add(GTK_CONTAINER(window), vbox);
gtk_widget_show_all(window);
gtk_main();
return 0;
}
Intead of using boxes (which may be a bit difficult to use because you have to figure out how things expand), try using the more powerful GtkGrid. It works with the hexpand/vexpand properties of the chidren like I said above.

opencv image update in gtk for video streaming linux with C programming

I am using opencv 1.0.0 and gtk2.0. I want to grab images continuously from a video stream. So far I have successfully been able to grab still image. This is non standard IP camera not VGA/USB /V4L one so need to know explicit method to refresh or update images continuously for video streaming!
GtkWidget *image;
...
...
IplImage* bayerImage = NULL;
IplImage* rgbImage = NULL;
...
...
...
cvCvtColor( bayerImage, rgbImage, CV_BayerBG2RGB );
// Usually opencv image is BGR, so we need to change it to RGB
pix = gdk_pixbuf_new_from_data ((guchar*)rgbImage->imageData,
GDK_COLORSPACE_RGB,
FALSE,
rgbImage->depth,
rgbImage->width,
rgbImage->height,
(rgbImage->widthStep),
NULL,
NULL);
image = gtk_image_new_from_pixbuf (pix);
/* (c) 2010 Virgoptrex. Feel Free to use. Leave credits intact */
#include gtk/gtk.h
gint t=0;
gboolean
expose_event_callback (GtkWidget *widget, GdkEventExpose *event, gpointer data)
{
//g_object_ref_sink (widget->window);
// gdk_drawable_ref (widget->window);
gdk_draw_arc (widget->window,
widget->style->fg_gc[GTK_WIDGET_STATE (widget)],
TRUE,
0, 0, widget->allocation.width, widget->allocation.height,
0, 64 * 18*t);
//gdk_drawable_unref (widget->window);
return TRUE;
}
static gboolean
time_handler(GtkWidget *widget)
{
gtk_widget_queue_draw(GTK_WIDGET(widget));
if (t<20)
{ t++; }
else if (t >=20)
{ t=0; }
printf("hello %d\n",t);
return TRUE;
}
int main( int argc,
char *argv[] )
{
GtkWidget *window;
GtkWidget *aspect_frame;
GtkWidget *drawing_area;
gtk_init (&argc, &argv);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_window_set_title (GTK_WINDOW (window), "Aspect Frame");
g_signal_connect (G_OBJECT (window), "destroy",
G_CALLBACK (gtk_main_quit), NULL);
gtk_container_set_border_width (GTK_CONTAINER (window), 10);
/* Create an aspect_frame and add it to our toplevel window */
aspect_frame = gtk_aspect_frame_new ("2x1", /* label */
0.5, /* center x */
0.5, /* center y */
2, /* xsize/ysize = 2 */
FALSE /* ignore child's aspect */);
gtk_container_add (GTK_CONTAINER (window), aspect_frame);
gtk_widget_show (aspect_frame);
/* Now add a child widget to the aspect frame */
drawing_area = gtk_drawing_area_new ();
/* Ask for a 200x200 window, but the AspectFrame will give us a 200x100
* window since we are forcing a 2x1 aspect ratio */
gtk_widget_set_size_request (drawing_area, 200, 200);
gtk_container_add (GTK_CONTAINER (aspect_frame), drawing_area);
gtk_widget_show (drawing_area);
g_signal_connect (G_OBJECT (drawing_area), "expose_event",
G_CALLBACK (expose_event_callback), NULL);
g_timeout_add(100, (GSourceFunc) time_handler, (gpointer)drawing_area);
gtk_widget_show (window);
gtk_main ();
return 0;
}