I'm working on a PyGTK/glade application that currently has 16 windows/dialogs and is about 130KB, and will eventually have around 25 windows/dialogs and be around 200KB. Currently, I'm storing all the windows in one monolithic glade file. When I run a window I call it like...
self.wTree = gtk.glade.XML("interface.glade", "WindowXYZ")
I wonder if it would be a better idea to split each window into it's own glade file. Instead of one glade file with 25 windows/dialogs I'd have 25 glade files with one window/dialog each and call it like so:
self.wTree = gtk.glade.XML("windowxyz.glade")
What do you guys think is the best way to do this? Is one method more resource intensive than another? One thing that would be nice about going to individual glade files is that naming widgets would be easier. For example, I name all my OK buttons "windowxyz_ok", but I could change it to simply "ok" instead. Makes things simpler. The downside is that it may be a bit less convenient to make changes to different windows.
I'm open to any and all arguments. Thanks!
In my projects, I always have one window per glade file. I'd recommend the same for your project.
The following are the two main reasons:
It will be faster and use less memory, since each call to gtk.glade.XML() parses the whole thing. Sure you can pass in the root argument to avoid creating the widget tree for all windows, but you'd still have to parse all the XML, even if you're not interested in it.
Conceptually its easier to understand if have one toplevel per window. You easily know which filename a given dialog/window is in just by looking at the filename.
Did you take some timings to find out whether it makes a difference?
The problem is that, as far as I understand it, Glade always creates all widgets when it parses an XML file, so if you open the XML file and only read a single widget, you are wasting a lot of resources.
The other problem is that you need to re-read the file if you want to have another instance of that widget.
The way I did it before was to put all widgets that were created only once (like the about window, the main window etc) into one glade file, and separate glade files for widgets that needed to be created several times.
I use different glade files for different windows. But I keep dialog associated with a window in the same glade file. As you said, the naming problem is annoying.
I have one glade file with 2 windows. It's about 450kb in size and I have not seen any slowdowns using libglademm with GTKmm.
Related
I have been working on a note taking program for myself and it is going well however I have had a lot of problems with getting all my widgets placed where I want them using the .pack() or .grid() options.
After looking around I found that I could use the .place() option instead. Before I decided to use .place() I found countless forum post saying "don't use .place()!".
I was at a stand still with my other options so I decided to give .place() a try. It turns out .place() is exactly what I needed to fix my layout issues and I just don't understand why everyone is hating on .place() so much.
Is there something inherently wrong with .place()? Or do people just prefer to use .pack() and .grid() for some practical reason other than ease of use?
I'm not sure what evidence you have that says everyone says not to use place. I suspect if you're judging by stackoverflow posts, you're mostly reading my opinion a hundred times rather than a hundred different opinions.
I recommend against place mainly because it requires more work to make a UI that is responsive to changes in fonts, resolutions, and window sizes. While it's possible to write a GUI that uses place and is responsive to those things, it requires a lot of work to get right.
One advantage that both pack and grid have over place is that they allow tkinter to properly configure the size of the root and Toplevel windows. With place you must hard-code a size. Tkinter is remarkably good at making windows to be the exact right size without you having to decide on explicit sizes.
In addition, long term maintenance of applications that use place is difficult. If you want to add a new widget, you will almost certainly have to adjust every other widget. With grid and pack it's much easier to add and remove widgets without having to change the layout of all of the other widgets. If I've learned anything over years of using tk and tkinter is that my widget layout changes a lot during development.
place is mostly useful for edge cases. For example, if you want to center a single widget inside another widget, place is fantastic. Also, if you want to place a widget such that it is independent of other widgets, place is great for that too.
There's nothing really wrong with .place, although using grid and pack give you more maintainable code. If you want to add a feature then place would require you to alter loads of absolute placements to fit a button in, for example.
If you need to use it then use it, there's no real problem with it, it just isn't the most maintainable solution to many problems. As you say, it's a matter of preference and ease of use.
Edit: there's an excellent answer you can read about it here.
I am writing a simple application and am using glade (gtk) for the UI. I need many windows (~10), of which one will open depending upon the command line flags, other contextual stuff etc.
Now, all these windows are pretty much similar, they have 3 top level tabs, the last tab is the same in all, all have a OK and Quit button etc., so I am looking for a way to build these windows in glade. I could copy paste one window and make the changes in that, but I am looking for a better way, that will allow me to reuse the common parts of the windows.
Also, I am using pygtk for loading up the windows.
Design a widget with the common aspects you mention. Wherever you need to implement something different, put a GtkAlignment with an appropriate name. Don't forget to change the alignment and fill values of the GtkAlignment.
In PyGTK you can gtk.Builder.get_object(name) to get access to these empty regions and add the extra components within them (which can also be designed with Glade).
Ok, with the help of detly's answer, I am able to get something working. For anyone who needs it, here is what I did.
main.glade contains the window and all the common cruft that I need to be displayed in all windows. comp.glade contains a window, with a vbox component with the extra stuff I need, lets call it 'top_comp'.
Now, in main.glade, I put a gtk.Alignment component in the place where I need the extra component to load, and call it, say, 'comp_holder'. With the builder I have, I do
builder = gtk.Builder()
builder.add_from_file('main.glade'))
builder.add_from_file('comp.glade'))
builder.get_object('top_comp').reparent(builder.get_object('comp_holder'))
This method seems to work for now, but I don't know if it is the correct way to do this thing.
Any suggestions for the above welcome.
I want to embed a window into another window, kind of like this:
EDIT: Screenshots deleted, sorry!
That is a wingdows program and was not made with GTK tough.
I tried using plugs and sockets, but apparently I can't put a gtk.Window (a toplevel window) on a plug.
Is it possible? If so, how? If not, what do you think I should do instead?
gtk.Window is derived from gtk.Bin, so it can only contain one single child. This again can be used in the following way:
Load both windows (e.g. from Glade files)
Remove the child from the second window, but save a reference to the child
Add the child somewhere in the first window
The second step would look like this:
childWidget = secondWindow.get_child()
secondWindow.remove(childWidget)
I'm using this approach to add plugin windows as tabs in one of my PyGTK applications. That means main window and plugins can be designed separately in Glade, and also implemented independently. Of course you're free to add the child widget anywhere you want.
I am attempting to create my first OS-level GUI using wxPython. I have the book wxPython in Action and have looked at the code demos. I have no experience with event-driven programming (aside from some Javascript), sizers, and all of the typical GUI elements. The book is organized a little strangely and assumes I know far more about OS GUI programming than I actually do. I'm fairly recent to object-oriented programming, as well. I'm aware that I am clearly out of my depth.
My application, on the GUI side, is simple: mostly a set of reminder screens ("Turn on the scanner," "Turn on the printer," etc) and background actions in Python either in the filesystem or from hitting a web service, but it is just complex enough that the Wizard class does not quite seem to cover it. I have to change the names on the "Back" and "Next" buttons, disable them at times, and so forth.
What is the standard process for an application such as mine?
1) Create a single wxFrame, then put all of my wxPanels inside of it, hiding all but one, then performing a sequence of hides and shows as the "Next" button (or the current equivalent) are triggered?
2) Create multiple wxFrames, with one wxPanel in each, then switch between them?
3) Some non-obvious fashion of changing the names of the buttons in wxWizard and disabling them?
4) Something I have not anticipated in the three categories above.
I don't have a good understanding of your application, but trying to force wxWizard to suit your needs sounds like a bad idea.
I suggest checking out the Demos available from the wxPython website. Go through each demo and I bet you'll find one that suits your needs.
I've personally never used wxWizard as I find it too cumbersome. Instead, I create a sequence of dialogs that do what I need.
I am just starting to learn Glade with pyGTK. Since Glade makes XML files instead of actual python code, is there a good way to start a project with Glade and then hand code more or tweak it?
Are there times or reasons it would be preferrable to hand code all of it instead of starting with glade?
GUI's created with glade are accessible in the code in two way: libglade or gtkbuilder. I cannot comment much on the differences between the two, other than that gtkbuilder is newer; there are a lot of pages on google that show how to migrate from libglade to gtkbuilder.
Using gtkbuilder, you can create your GUI object by retrieving it from the the XML file using gtkbuilder. This creates the object with all of the settings you set in glade. You now have an GUI object which you can manipulate via it's regular interface.
builder = gtk.Builder()
builder.add_from_file(glade_path)
builder.connect_signals(self)
main_window = builder.get_object("main_window")
main_window.show()
text_box1 = builder.get_object("textbox1")
text_box1.set_text("enter your name")
Line 3 shows how signal handlers are attached when loaded from glade. Essentially, it looks for the function you specified for the signal in the glade interface and attached to it; if the function isn't provided, you'll see a warning on the command line.
How much do you know about glade and pygtk? Glade creates xml files but you load these using gtk.Builder in python. You can easily tweak any widgets you created with glade in python. Read these tutorials to understand how to do it better. You just need to learn more about pygtk and glade and it will be obvious.