I have a very simple code, wich create a GtkWindow and place in it a GtkButton.
window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_widget_set_size_request(_window, 800, 450);
gtk_window_set_decorated(GTK_WINDOW (_window), FALSE);
gtk_window_set_position(GTK_WINDOW (_window),GTK_WIN_POS_CENTER_ALWAYS);
gtk_window_set_resizable(GTK_WINDOW (_window), FALSE);
_startbutton = gtk_button_new_with_label("myLabel");
gtk_container_add(GTK_CONTAINER(_window), _startbutton);
gtk_widget_show_all(_window);
Yet, this doesn't work as expected because the button fills the whole window.
I tried to find a way to change the button size, but all the methods that i found use some methods that are deprecated...
Can someone explain to me the way to do this ?
Because the GtkButton is the only control in the GtkWindow, it will be given the entire area of the GtkWindow to fill. If you want to do anything more complicated, you will need to use layout containers like GtkBox and GtkGrid to explicitly lay out the button, usually in relation to other controls that you will also have in the window.
Once you do lay out your controls, you can use expansion and alignment to control how the button makes use of its allotted space.
Related
I'm trying to write an interface in GTK+2, and I can't find a way to make sure toggle buttons and progress bars won't try to fill up entire space avaiable to them.
My interface has a picture, and a bunch of progress bars and toggle buttons on the other side. If there's enough of them to make the entire vbox with them higher than the picture itself, everything is fine:
However, when there isn't enough of them, they get vertically stretched, which makes them look wrong:
I can't find any way to make sure this doesn't happen, the only thing that I found in the documentation related to setting height of these widgets is setting their minimal height. I'm looking for a way to ensure these widgets don't try to take up all space they can.
My code is here. I couldn't include the placeholder image that I'm using here, but it's just a 128x128 placeholder that can be easily replaced if needed.
When you create your widget for a single CPU, you add it to the parent container:
gtk_container_add(GTK_CONTAINER (vbox), current->box);
Container functions are generic for multiple types of widgets to hold children but don't allow specific adjustments.
In a box you can specify whether the available space should be added to the child widget and how it should appear.
To use this you need to change this line to:
gtk_box_pack_start(GTK_BOX(vbox), current->box, FALSE, FALSE, <borderline>);
This should prevent the widget to be enlarged.
I am currently coding in C for linux and I need a GUI, so I took the GTK library to do so . I now have a window with a label (to begin with) but I don't know how to move it (in (x,y) coordinates, not in zPosition) to put it at the top of the window.
Here is my GTK code in main()
//Label
pLabel=gtk_label_new(NULL);
sUtf8 = g_locale_to_utf8("<span font_desc=\"Times New Roman italic 12\" foreground=\"#0000FF\">Neural Network - XOR Example</span>\n"
,-1, NULL, NULL, NULL);
gtk_label_set_markup(GTK_LABEL(pLabel), sUtf8);
g_free(sUtf8);
gtk_label_set_justify(GTK_LABEL(pLabel), GTK_JUSTIFY_CENTER);
//Window
gtk_window_set_position(GTK_WINDOW(pWindow), GTK_WIN_POS_CENTER);
gtk_window_set_title(GTK_WINDOW(pWindow), "Neural Network");
gtk_window_set_default_size(GTK_WINDOW(pWindow), 900, 600);
gtk_container_add(GTK_CONTAINER(pWindow), pLabel);
g_signal_connect(G_OBJECT(pWindow), "destroy", G_CALLBACK(OnDestroy), NULL);
gtk_widget_show_all(pWindow);
gtk_main();
Has anybody an idea on how to move it ?
Thank you!
Here is what I got:
(source: hostingpics.net)
carl gave you part of the answer.
As to why you see what you have, there are two parts:
First, GtkLabel has an archaic alignment mechanism it inherits from the deprecated GtkMisc class. See GtkMisc's documentation for details: the xalign and yalign properties control the position of the text within the label's allocation, and it's set to centered by default. But remember that they are deprecated, so there's usually better alternatives.
Second, you can only have one control in a GtkWindow. This control gets allocated the entire space of the window.
Put these two facts together and you should see why you have what you have.
So what is correct instead?
You have to use a container, such as GtkBox or GtkGrid, to get more than one widget into a GtkWindow. Each widget carries with it four special properties: hexpand, halign, vexpand, and valign which control the position and size of each member of the container. These are properties of the widgets themselves.
hexpand and vexpand determine whether or not the container allocates whatever space is left over to this control in the X and Y directions, respectively. If multiple widgets have expand set, the space is divided evenly.
halign and valign determine the position of a widget in its allocation. GTK_ALIGN_START, GTK_ALIGN_CENTER, and GTK_ALIGN_END put the widget at the start, middle, and end of the given alignment side, respectively. GTK_ALIGN_FILL fills the widget to fit the allocation.
This page has more information.
If you're trying to do exact positioning of controls, you should first investigate if GtkGrid and GtkBox (applied recursively) provide what you want. An important thing about the default internal centering of GtkLabels is that a GtkLabel in a GtkGrid will already be vertically aligned to its neighbor's text; just set halign to start or end to get the label left-aligned or right-aligned (and set valign to start if its neighbor is something big like a table). There are also functions that provide margins and padding to make the UI look nice.
If you absolutely must position things yourself, however, keep everything in mind.
I am currently working on an existing Linux application called Xpad, which is a sticky notes application written in C. I try to implement transparency but I have a hard time achieving what I want. A sticky note looks like this.
I have a (toplevel) gtk_window with a gtk_textview.
If the background color of the textview is set with the function gtk_widget_override_background_color() to a transparant color (GdkRGBA where alpha value is smaller than 1), the color of the gtk_window behind it, becomes more visible.
However, I don't want to see the gtk_window, but the applications behind the gtk_window, such as the browser, libreoffice, or the desktop.
If the gtk_window is set to a certain transparancy, either with gtk_widget_override_background_color() or with gtk_widget_set_opacity(), the whole widget, including the window decorations become (partially) transparent.
To make the relations between the visible objects more clear, I have created a diagram of the different parts, and marked the place where I believe the transparency issue is taking place.
Anybody have any ideas how to make the textview background transparent, without making the window decorations transparent, so I can see whatever is behind this application?
Set a proper RGBA visual for the widget
w = //some GtkWidget or GtkWidget derived klass (i.e. GtkWindow)
gtk_widget_set_app_paintable (w, TRUE); // important or you will get solid color
// the next 3 lines should be wrapped in a func which is also hooked to "screen-changed"
GdkScreen *screen = gtk_widget_get_screen (w);
GdkVisual *visual = gdk_screen_get_rgba_visual (screen);
gtk_widget_set_visual(w, visual);
gtk_widget_show_all(w);
g_signal_connect(G_OBJECT(w), "screen-changed", G_CALLBACK(screen_changed_contaniing_above_code), NULL);
I have a program which shows two GtkTreeViews packed inside a GtkPaned (sscce: here):
gtk_paned_add1(GTK_PANED(paned), tree_view1);
gtk_paned_add2(GTK_PANED(paned), tree_view2);
The result is the following:
However, the tables can become bigger, so I added then to GtkScrolledWindows (sscce: here):
GtkWidget *scrolled_window1 = gtk_scrolled_window_new(NULL, NULL),
*scrolled_window2 = gtk_scrolled_window_new(NULL, NULL);
gtk_container_add(GTK_CONTAINER(scrolled_window1), tree_view1);
gtk_container_add(GTK_CONTAINER(scrolled_window2), tree_view2);
gtk_paned_add1(GTK_PANED(paned), scrolled_window1);
gtk_paned_add2(GTK_PANED(paned), scrolled_window2);
However, now the window collapses itself to the point it is almost a thin trance, as in the screenshot below:
If I maximize the window, the first column does not appear (although I can manually expand it):
So, what is the best method of getting the appearance of the first screenshot wen using GtkScrolledWindows in this scenario? Also, could I define the size of the pane columns in relation to one another (for example, 30% for the first one, 70% for the second one?
I've been using this pattern (I'd be happy if someone posted a better answer):
GtkWidget* treeView_, pane1_;
// [Removed code to create and show the widget heirarchy.]
GtkRequisition sizeReq;
gtk_widget_size_request(treeView_, &sizeReq); // get tree's preferred size
gtk_paned_set_position(GTK_PANED(pane1_), sizeReq.width);
This gets pretty close, but you'll probably have a horizontal scrollbar with a few hidden pixels. Since our application remembers the user's adjustments to the pane positions, it only needs to look "good enough" on initial layout.
Also, there are requirements for gtk_widget_size_request() returning something meaningful. In my case, I've invoked a gtk_widget_show_all() on the hierarchy before retrieving the size request.
The solution I adopted was to actually set the size of the scrolled windows (sscce):
gtk_widget_set_size_request(scrolled_window1, 200, 600);
gtk_widget_set_size_request(scrolled_window2, 600, 600);
The result was, as one would expect, a window with 800x600:
I am not satisfied: this approach relies on arbitrary sizes and it seems too "manual". Nonetheless, I want to use my software so I will adopt it for now.
I'm using one 3rd party SDK which get hwnd (window handle) and paints something on my window. And i want to specify window painting region (left, right, top, bottom) ? How it's possible to do it ? I'm found WINAPI function SetWindowRgn, but it's not good for me because this function specify whole window region. I need specify just window painting area.
SetWindowRgn() is exactly what you need. You can create your region from a rectangle using CreateRectRgn(). A good introduction to window regions can be found here.
Alternatively you can modify the non-client area of your window, but I would not recommend that, because it has several side-effects.
If it's possible to give this library an HDC instead of the window handle - you should do this.
That is, get the drawing DC for your window's client area (GetDC), create the needed clipping region, and set it (SelectClipRgn).
In case your library insists on accepting the window handle - I can propose the following solution:
Inside your window create another child window, set the appropriate region for it. And give the handle of that window to your library.