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.
Related
Let's say that I open up some word file with a macro that opens up a dialog with some buttons.
Is there a way to find those buttons automatically and press them (when having only the PID)?
Currently, I'm using pywinauto to automate the GUI testing. If there's a way to do it with pywinauto that would be great.
Thanks.
To summarize all the comments:
It's possible to enumerate all the windows and their controls using methods .windows() (for top-level windows), immediate .children() and all the .descendants() (the whole subtree as a plain list). You can even filter children and descendants by class_name, control_type, content_only and/or title.
Example:
print(app.windows()[0].descendants(control_type='Edit'))
I am currently working on a project using Python and tkinter.
The problem is that I don't know what's the proper way to display multiple windows, or screens, I don't know how to call them. Let me explain better.
When the application starts the login screen appears. After that, if I click register, I want to go to the register screen, but I don't want it to be a separate window (I don't want to have 2 windows displayed at the same time), but rather another window with different content ?!
How should I handle properly this situation? Create a second window using Toplevel and hiding the first (can I do that?) or changing the widgets of the first?
Code I've written so far
You can do that- just call window.withdraw() on the Toplevel you need to hide after creating a new Toplevel. Changing the widgets in the first is also an option- if you like, you could always try a Notebook widget and disable manual flipping or just put each "screen" in a frame and grid_ or pack_forget them to remove them from the window.
I am using BalloonTip and BalloonFrame from wxpython in order to generate pop up notifications. Unfortunately the generated elements are overlapping all windows: Not only the window of my application but also all windows of the other applications.
I would like to suppress this behavior and display the notification only on top of my own application and not on top of all windows.
Is there any possibility to specify the "z-index" like in CSS or something similar?
You should probably just create your own frame then as I don't believe the Balloon widgets support that behavior. When you do create your own frame, you can tell it to center on parent. If you want it to disappear on it's own, you can use a wx.Timer. You could also look at this:
http://wxpython.org/Phoenix/docs/html/adv.NotificationMessage.html
In python, I enumerate top-level windows through EnumWindows, and also I enumerate the processes through EnumProcesses.
Then in the python script, I put all the window handles which belongs to the same pid into one list (I did this through GetWindowThreadProcessId).
Later I found out something: there are 3 window handles which belong to notepad.exe, but I only open one text file.
Why?
Besides, I tried to set the text window as the foreground window through SetForegroundWindow, I passed the three window handles to this function, and two work.
How could this be ?
Processes sometimes create invisible windows for their own purposes. You should ignore them (use IsWindowVisible function).
To investigate this kind of things your best friend is Spy++, that comes with several versions of Visual Studio, if you can get it.
According to it, notepad.exe creates three top-level windows:
The visible main window, class name "Notepad", overlapped.
A hidden, disabled, pop-up window, class name "MSCTFIME UI", caption "M".
Another hidden, disabled, pop-up window, class name "IME", caption "Default IME".
The two hidden windows are used internally by notepad to implement the IME (Input Method Editor), the GUI to type complex scripts.
Many programs create top-level hidden windows for a lot of things. For what you intend, you can ignore them all and use only the visible ones.
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.