gtk3 GtkWindow title bar color - gtk3

Using gtk3, how can I change the default GtkWindow titlebar color? Would it involve GtkStyleContext? I've only used GtkCssProvider.

You can't change the titlebar color from GTK. The titlebar is drawn by the window manager, and GTK doesn't "know" anything about it. You can only communicate with the window manager through "hints", such as whether the window should have a titlebar or what string should be displayed there, but the window manager is free to ignore them.

You can do it...
( at least on Linux )
What happens is that your window is being un-decorated then "decorated" with a header bar ( which happens to have a bloody "show_close_button", so I guess this is an intended use )
class base_ui(Gtk.Window):
def __init__(self):
# initializing self ( the window )
Gtk.Window.__init__(self, title="window title")
self.set_border_width(1)
self.set_default_size(800, 600)
# Create the header bar
hb = Gtk.HeaderBar()
# This is the id of the header bar to be used in the css file
hb.set_name("mw_hb")
# we can even set a close button ...
# you can add the other buttons as well, but have to do it yourself
hb.set_show_close_button(True)
# the effective text in the titlebar ( the window title )
# is props.title
hb.props.title = "win title"
# and here comes the sun - we set our headerbar as the new titlebar.
# Bazinga
self.set_titlebar(hb)

Related

Setting value for title of NSOpenPanel does not work

I want to set title for my NSOpenPanel, but it does not work! Apple says:
Gets and sets the title for the panel shown at the top of the window.
But I can not make codes works, not sure what is wrong?
let nsOpenPanel = NSOpenPanel()
nsOpenPanel.canChooseFiles = true
nsOpenPanel.title = "Hello, Choose Files"
if (nsOpenPanel.runModal() == .OK) ... // rest of codes ...
The title is something from the past when windows in macOS had title bars. To show text or an instruction on top of the NSOpenPanel object, use the message property:
nsOpenPanel.message = "Hello, Choose Files"

Gtk Button inner-border

I add a button to HBox, with expand equal to False, but I want the button to have more spacing between its label and border. I assume it is "inner-border" property, but it is read-only. How can I set it to e.g. 4px?
gtk.Label is a subclass of gtk.Misc which has the method set_padding. If you get the label out of the gtk.Button then you can just call set_padding on it.
You could do something like:
label = gtk.Label("Hello World")
button = gtk.Button()
/* Add 10 pixels border around the label */
label.set_padding(10, 10)
/* Add the label to the button */
button.add(label)
/* Show the label as the button will assume it is already shown */
label.show()
Wrong answer:
What you're looking for is called "padding". When you add your button to the container, for example by calling gtk.Box.pack_start, just set the padding parameter to a positive integer.
Update:
Seems I misread the question. In that case, my guess is that you're supposed to use gtk_widget_modify_style, as inner-border is a style property. You'll first get the style modifier you need by calling gtk_widget_get_modifier_style. You'll then be able to modify the style only for that button using the ressource styles matching rules.
you can use "inner-border" style property of gtk button.
here, small code snippets
In gtkrc file:
style "button_style"
{
GtkButton::inner-border = {10,10,10,10}
}
class "GtkButton" style "button_style"
In .py file:
gtk.rc_parse(rc_file_path + rc_file)
[Edit]
In gtkrc file:
style "button_style"
{
GtkButton::inner-border = {10,10,10,10}
}
widget "*.StyleButton" style "button_style" # apply style for specific name of widget
In .py file:
gtk.rc_parse(rc_file_path + rc_file)
#set name of button
self.style_button.set_name('StyleButton')
hope, it would be helpful.
I sometimes just add spaces in the label !
gtk.Button(" Label ")
to get some spacing.
Hope this could help you.

Pygtk: Remove a widget from a container and reuse it later

I'm using a custom container where I need to reorder widgets but there are no methods to do it. So I tried to remove all the widgets and add them again in order.
The problem is that this is not working well, I can't see the widgets after adding them again, I guess what's happening is that when I remove the widgets they become unrealized.
Is there any way of removing a widget an reuse it later?
The pygtk docs provide a bit of insight.
Note that the container will own a
reference to widget, and that this may
be the last reference held; so
removing a widget from its container
can cause that widget to be destroyed.
If you want to use widget again, you
should add a reference to it.
EDITS
I just quickly modified pygtk's Hello World to add/remove/reorder widgets in a container. This works because the button1 is a member variable of the class, it never goes out of scope.
#!/usr/bin/env python
# example helloworld2.py
import pygtk
pygtk.require('2.0')
import gtk
class HelloWorld2:
# Our new improved callback. The data passed to this method
# is printed to stdout.
def callback_remove(self, widget, data):
self.box1.remove(self.button1);
def callback_add(self, widget, data):
self.box1.pack_start(self.button1, True, True, 0)
# another callback
def delete_event(self, widget, event, data=None):
gtk.main_quit()
return False
def __init__(self):
# Create a new window
self.window = gtk.Window(gtk.WINDOW_TOPLEVEL)
# This is a new call, which just sets the title of our
# new window to "Hello Buttons!"
self.window.set_title("Hello Buttons!")
# Here we just set a handler for delete_event that immediately
# exits GTK.
self.window.connect("delete_event", self.delete_event)
# Sets the border width of the window.
self.window.set_border_width(10)
# We create a box to pack widgets into. This is described in detail
# in the "packing" section. The box is not really visible, it
# is just used as a tool to arrange widgets.
self.box1 = gtk.HBox(False, 0)
# Put the box into the main window.
self.window.add(self.box1)
# Creates a new button with the label "Button 1".
self.button1 = gtk.Button("Button 1")
# Now when the button is clicked, we call the "callback" method
# with a pointer to "button 1" as its argument
self.button1.connect("clicked", self.callback_remove, "button 1")
# Instead of add(), we pack this button into the invisible
# box, which has been packed into the window.
self.box1.pack_start(self.button1, True, True, 0)
# Always remember this step, this tells GTK that our preparation for
# this button is complete, and it can now be displayed.
self.button1.show()
# Do these same steps again to create a second button
self.button2 = gtk.Button("Button 2")
# Call the same callback method with a different argument,
# passing a pointer to "button 2" instead.
self.button2.connect("clicked", self.callback_add, "button 2")
self.box1.pack_start(self.button2, True, True, 0)
# The order in which we show the buttons is not really important, but I
# recommend showing the window last, so it all pops up at once.
self.button2.show()
self.box1.show()
self.window.show()
def main():
gtk.main()
if __name__ == "__main__":
hello = HelloWorld2()
main()
Just set the widget's visibility property to False, and set it to True later, with the set_visible method.
no he need only widgrt.its objects not need.then visible must not used.it will only hide graphicaly.but memmory still not released
remove function is the answer

How do I add a background image to a GTK TreeView?

I would like to to have a GTK TreeView with a background image as shown in the mockup below.
I have found methods for setting the background color of widgets, but there does not appear to be a method for setting a background pixbuf or other image format.
I'm using Python with PyGTK but an answer in any language with GTK bindings is acceptable.
Mockup of gtkTreeView with background image:
First Attempt
Based on Jong Bor's advice, I tried the following:
style = treeview.get_style().copy()
img_pixbuf = gtk.gdk.pixbuf_new_from_file(image_filename)
img_pixmap = img_pixbuf.render_pixmap_and_mask()[0]
for state in (gtk.STATE_NORMAL, gtk.STATE_ACTIVE, gtk.STATE_PRELIGHT,
gtk.STATE_SELECTED, gtk.STATE_INSENSITIVE):
style.bg_pixmap[state] = img_pixmap
treeview.set_style(style)
At first this didn't seem to have any effect, but upon selecting an item in my TreeView I observed the following:
Part of the background 'shows through' when a row is selected.
(Note that I'm using a background image based on my mockup, except that it has some blue color, for test purposes).
I then activated part of my GUI that clears the contents of the TreeView and redraws it, and observed this:
However as soon as I add something to the TreeView the background disappears, so I'm still not sure if this is going in the right direction.
I suspect that since each cell has a renderer which controls its appearance, you would have to somehow modify the treeview cell by cell.
Anyway, the following code might be worth a try (untested, incomplete code):
# Get the treeview's style
style = treeview.get_style().copy()
# Change the bg_pixmap attribute
# It's an array with one pixbuf for every widget state, so
# you probably want to replace each of the default
# pixmap's with your own image(s)
#
style.bg_pixmap[0] = your_pixmap
style.bg_pixmap[1] = your_pixmap
style.bg_pixmap[2] = your_pixmap
style.bg_pixmap[3] = your_pixmap
style.bg_pixmap[4] = your_pixmap
# Set the modified style
treeview.set_style(style)
The bg_pixmap attribute is documented in the PyGTK reference.
I'm not sure of how the array positions map to widget states. If it is the same as in c++, it will be:
0 - STATE_NORMAL
1 - STATE_ACTIVE
2 - STATE_PRELIGHT
3 - STATE_SELECTED
4 - STATE_INSENSITIVE
Using GTK3 and gtkmm it is possible to use CSS, but the image needs to available as a file or possibly a resources.
Here I assume that the treeview is subclassed:
class MyTreeView : public Gtk::TreeView { .. };
for you treeview set a name and then add a CSS style to it:
MyTreeView::MyTreeView () {
set_name ("MyTreeView");
auto css = Gtk::CssProvider::create ();
auto sc = get_style_context ();
string path_to_img = "my-image.png";
string css_data =
ustring::compose (
"#MyTreeView { background-image: url(\"%1\");"
" background-repeat: no-repeat;"
" background-position: 50%% 50%%;"
" }\n"
"#MyTreeView .hide_bg { background-image: none; }",
path_to_img);
try {
css->load_from_data (css_data);
} catch (Gtk::CssProviderError &e) {
cout "error: attempted to set background image: " << path_to_img.c_str () << ": " << e.what () << endl;
}
auto screen = Gdk::Screen::get_default ();
sc->add_provider_for_screen (screen, css, GTK_STYLE_PROVIDER_PRIORITY_APPLICATION);
}
it seems that it is also possible to set the background of the row to transparent by adding:
background: none;
to the CSS.
The background image can then be hidden or shown using:
if (!hide) {
auto sc = get_style_context ();
if (!sc->has_class ("hide_bg")) sc->add_class ("hide_bg");
} else {
auto sc = get_style_context ();
if (sc->has_class ("hide_bg")) sc->remove_class ("hide_bg");
}

GXT LayoutContainer with scrollbar reports a client height value which includes the area below the scrollbar

I have this code which sets up a "main" container into which other modules of the application will go.
LayoutContainer c = new LayoutContainer();
c.setScrollMode(Scroll.ALWAYS);
parentContainer.add(c, <...>);
Then later on, I have the following as an event handler
pContainer = c; // pContainer is actually a parameter, but it has c's value
pContainer.removeAll();
pContainer.setLayout(new FitLayout());
LayoutContainer wrapperContainer = new LayoutContainer();
wrapperContainer.setLayout(new BorderLayout());
wrapperContainer.setBorders(false);
pContainer.add(wrapperContainer);
LayoutContainer west = pWestContentContainer;
BorderLayoutData westLayoutData = new BorderLayoutData(LayoutRegion.WEST);
westLayoutData.setSize(pWidth);
westLayoutData.setSplit(true);
wrapperContainer.add(west, westLayoutData);
LayoutContainer center = new LayoutContainer();
wrapperContainer.add(center, new BorderLayoutData(LayoutRegion.CENTER));
pCallback.withSplitContainer(center);
pContainer.layout();
So in effect, the container called 'west' here will be where the module's UI gets displayed. That module UI then does a simple rowlayout with two children. The botton child has RowData(1, 1) so it fills up all the available space.
My problem is that the c (parent) container reports a height and width value which includes the value underneath the scrollbars. What I would like is that the scrollbars show all the space excluding their own space.
This is a screenshot showing what I mean:
alt text http://img265.imageshack.us/img265/9206/scrollbar.png
Try adding padding equivalent to the scroll bars size 14px? on the container where the Scroll.Always is being applied