pygtk menubar with fixed - gtk

I'm new to pyGTK, and now I'm trying to create a menubar with a fixed layout, but I only get a background on the items, not on the entire bar. My code:
import gtk
class App(gtk.Window):
def __init__(self):
super(App,self).__init__()
self.set_size_request(640,480)
self.set_position(gtk.WIN_POS_CENTER)
menubar = gtk.MenuBar()
menu_file= gtk.Menu()
menuitem_file = gtk.MenuItem("File")
menuitem_file.set_submenu(menu_file)
menuitem_exit = gtk.MenuItem("Exit")
menuitem_exit.connect("activate",gtk.main_quit)
menu_file.append(menuitem_exit)
menubar.append(menuitem_file)
fixed = gtk.Fixed()
vbox = gtk.VBox(False, 2)
vbox.pack_start(menubar, False, False, 0)
fixed.add(vbox)
self.add(fixed)
self.connect("destroy",gtk.main_quit)
self.show_all()
App ()
gtk.main ()

You need to make vbox request size, e.g. add vbox.set_size_request (300,50) and see the difference. It is not correct size, but then I don't know why you use gtk.Fixed at all. In 99.95% of case you don't need gtk.Fixed. And especially if you are new to GTK+ you might think you need it while you actually don't.

Related

Editable label in Python GTK+ 3?

I'm new to GTK programming. I want to have a Label widget whose text can be edited, kind of like this: https://docs.gtk.org/gtk4/class.EditableLabel.html.
The problem is I have no idea how to implement this. I understand that Gtk.Button has a set_label() function, though I don't know how to use it to make an editable label.
You can do that with Gtk.Entry which you can set_editable based on "something". Example with check button would look something like this:
import gi
gi.require_version("Gtk", "3.0")
from gi.repository import Gtk
def on_editable_toggled(button, entry):
value = button.get_active()
entry.set_editable(value)
entry.set_sensitive(value)
win = Gtk.Window()
win.connect("destroy", Gtk.main_quit)
vbox = Gtk.Box(orientation=Gtk.Orientation.VERTICAL, spacing=6)
win.add(vbox)
entry = Gtk.Entry()
entry.set_text("Hello World")
vbox.pack_start(entry, True, True, 0)
check_editable = Gtk.CheckButton(label="Editable")
check_editable.connect("toggled", on_editable_toggled, entry)
check_editable.set_active(True)
vbox.pack_start(check_editable, True, True, 0)
win.show_all()
Gtk.main()
It doesn't really look like a label, but you can use the Gtk CSS styling to change the background and border colors to make it look like one when it is set to non-editable.

ProgressBar framerate drops when Label draws on top

I'd not normally ask for help here, but I'm stumped - this bug is the strangest thing I've seen in a long time.
https://gfycat.com/FluidFrigidEastsiberianlaika
I've got a simple UI object called GhostProgressBar that extends ScalaFX.StackPane and gives it two children - a ProgressBar and a Label. I noticed after adding it to some other UI screens that my framerate had plummeted, to a point where the UI was painfully unusuable.
The code for this is super simple:
import scalafx.geometry.Pos
import scalafx.scene.control.{Label, ProgressBar}
import scalafx.scene.layout.StackPane
class GhostProgressBar extends StackPane {
alignment = Pos.Center
val bar = new ProgressBar() {
prefWidth = Integer.MAX_VALUE
}
val text = new Label() {
id = "ProgressBarText"
text = "PERFORMANCE TESTING"
}
children = List(bar, text)
}
In the GIF I'm using it inside a VBox that's the center element of a regular BorderPane - nothing strange or atypical.
From the behaviour I've observed, I think it's an issue with text being drawn over the bar of the ProgressBar. Just now I've done some more debugging, and my suspicions that it was related to the styling of the text were confirmed.
This is the styling that's on the text in the GIF.
#ProgressBarText {
-fx-text-fill: #dddddd;
-fx-font-weight: bold;
}
#ProgressBarText .text {
-fx-stroke: #333333;
-fx-stroke-width: 1px;
-fx-stroke-type: outside;
}
When I remove that styling, the framerate doesn't drop when the bar hits the text.
What I can't figure out is why this is happening? Anyone got any ideas? I have no idea if it's a Scala thing, or a ScalaFX thing, whether or not it's reproducible with the same stuff in a JavaFX context.
Help would be appreciated.
EDIT: I was asked for versions, here we go:
Scala version: 2.12.7
ScalaFX version: 8.0.102-R11
JDK version: 1.8.0_181
JavaFX version: unknown, I'm not familiar with ScalaFX's internals and I'm not using JavaFX directly.
EDIT 2: I was asked to try the same screen elements, but using JavaFX elements instead of ScalaFX ones. Here's the code I used, the outcome was the same - whenever the outlined text was over the progress bar's bar, the framerate dropped.
import javafx.geometry.Pos
import javafx.scene.control.{Label, ProgressBar}
import javafx.scene.layout.StackPane
class JavaFXGhostProgressBar extends StackPane {
this.setAlignment(Pos.CENTER)
val bar = new ProgressBar()
bar.setMaxWidth(Double.MaxValue)
val text = new Label()
text.textProperty().setValue("PERFORMANCE TESTING")
text.idProperty().setValue("OutlineProgressBarText")
this.getChildren.addAll(bar, text)
}
I couldn't find out what version of JavaFX I used here; IntelliJ was weirdly inconsiderate in not telling me. I couldn't find it in my external libraries list, either.

How to prevent a Gtk widget from being "grayed out" when set insensitive?

I am using a Gtk EventBox which holds an image to receive mouse click events on the image. Once the image is clicked, the EventBox is set insensitive. However, since this results in the EventBox being "grayed out", the colors of my image become pale as well. I really don't like this. Is there any way to disable this kind of behaviour of Gtk widgets?
Code example:
var ebox = new EventBox ();
var img = new Image ();
img.set_from_file ("my_image.png");
img.show ();
ebox.add (img);
ebox.button_press_event.connect ( () => { ebox.set_sensitive (false); return true; } );
you could subclass the widget, add a virtual method do_draw(), and draw your image there.

How to get the background color of a widget in GTK and Python?

I want to get the normal background color of a widget (a GtkHeaderBar, in this case). I'm currently using
style = self.get_titlebar().get_style_context()
to get the style, and
color = style.get_property("background-color", Gtk.StateFlags.NORMAL)
to get the background color associated to that style.
However it returns a Gkd.RGBA object with the following properties:
Gdk.RGBA(red=0.000000, green=0.000000, blue=0.000000, alpha=0.000000)
But if I open GTK Inspector, select the HeaderBar, and goes to the style properties, it shows
background-color | rgb(57,63,63) | gtk-contained-dark.css:1568.29
What do I have to do to get these same values?
Edit:
I am experimenting with the GtkStyleContext.render_background(), but I'm having no success:
surfc = Cairo.ImageSurface (Cairo.FORMAT_ARGB32, 10, 10)
contx = Cairo.Context(surfc)
style = self.get_titlebar().get_style_context()
backg = Gtk.render_background(style, contx, 10, 10, 10, 10)
surfc.write_to_png("test.png")
The resulting file test.png is a rgba(0, 0, 0, 0) image.
You should have a look at modifying the background-color with css. There is a very good documentation of it. It can be used with python with
css_provider = Gtk.CssProvider()
css_provider.load_from_path('application.css')
Gtk.StyleContext.add_provider_for_screen(
Gdk.Screen.get_default(),
css_provider,
Gtk.STYLE_PROVIDER_PRIORITY_APPLICATION
)
and a css file like:
GtkHeaderbar {
background-color:#theme_bg_color;
}
EDIT: As you commented you do not want to modify the background color but retrieve the value of it. You can do widget.get_style_context().get_background_color() and it will return something like Gdk.RGBA(red=0.913725, green=0.913725, blue=0.913725, alpha=1.000000).
However, you should note that get_background_color() is deprecated since there is not one background color. Some widget use a gradient as a background so it is not the best solution to use this method. See the documentation for reference.
If anyone's interested, I think the problem lies here:
backg = Gtk.render_background(style, contx, 10, 10, 10, 10)
while it should be:
backg = Gtk.render_background(style, contx, 0, 0, 10, 10)
You were on the right track, but there is an issue with new recommended way to get colors.
The recommended workaround
is to fall back to the deprecated get_background_color()
import gi
gi.require_version('Gtk', '3.0')
from gi.repository import Gtk
import sys
window = Gtk.Window()
context = window.get_style_context()
# this one is buggy
color1 = context.get_property("background-color", Gtk.StateFlags.NORMAL)
print(color1)
# this is the deprecated version, but it is the recommended workaround
color2 = context.get_background_color(Gtk.StateFlags.NORMAL)
print(color2)
From the python/Gtk documentation,
Note that passing a state other than the current state of self is not recommended unless the style context has been saved with Gtk.StyleContext.save()
So the current recommended way to get a widget background color is
context = widget.get_style_context()
color = context.get_background_color(widget.get_state())
Often self is a Gtk widget, and this becomes
context = self.get_style_context()
color = context.get_background_color(self.get_state())

GTK+ widget is resizing itself within a Paned

I have GTK+ (Vala) app that has Main Window with a ScrolledWindow with a HPaned with two VTE Terminals in it. In some cases terminal itselfs resizes the paned. I don't want to allow terminal resize it, I only want to allow user to move with splitter and resize it.
I dont set any properties:
var sw1 = new Gtk.ScrolledWindow(null, null);
var sw2 = new Gtk.ScrolledWindow(null, null);
var paned = new Gtk.HPaned();
paned.pack1(sw1, true, true);
paned.pack2(sw2, true, true);
var main_box = new Gtk.VBox(false, 0);
main_box.pack_start(this.menubar, false);
main_box.pack_start(paned);
this.add(main_box);
How to do that? Why the Terminal (ScrolledWindow) is trying to resize? How can I prevent this behavior? Thanks.
The solution is to set
sw1.set_size_request(-1, 300);
sw2.set_size_request(-1, 300);
so it wont "scretch" while there are less lines.