I am new to Python GTK programming. In my UI i have a button. On click of that i have to open a popup which has a three button and some label. I have to pass some variables from main window to popup window. on click of buttons on the popup window I have to update this variable. Then once i close this popup window I need the updated value of the variables in main window.
1. Can I do this in Python GTK.
2. If yes how will i go about achieving it.
3. Can I use glade file for creating a glade file.
You probably need dialog boxes.
From pygtk :
import gtk
label = gtk.Label("Nice label")
dialog = gtk.Dialog("My dialog",
None,
gtk.DIALOG_MODAL | gtk.DIALOG_DESTROY_WITH_PARENT,
(gtk.STOCK_CANCEL, gtk.RESPONSE_REJECT,
gtk.STOCK_OK, gtk.RESPONSE_ACCEPT))
dialog.vbox.pack_start(label)
label.show()
checkbox = gtk.CheckButton("Useless checkbox")
dialog.action_area.pack_end(checkbox)
checkbox.show()
response = dialog.run()
dialog.destroy()
Related
I would like to disable the main window of my text adventure program while the character creation window is up. I am relatively new to this. When I try my code below, the main window stays interactable even though the secondary window (creator) is open. There is no error that the console puts out, it just doesn't work is all.
def characterCreator():
global creator
creator = Tk()
creator.title('Character Creator')
creator.geometry('300x400')
while creator.state=='normal':
root.state='disabled'
You should create your creator window as an instance of tkinter.Toplevel() rather than declaring a new instance of Tk() altogether, then you can use grab_set to prevent the user from interacting with the root window while the creator window is open.
import tkinter as tk
root = tk.Tk()
# usual root configs like title and geometry go here
creator = tk.Toplevel(root) # the Toplevel window is a child of the root window
# creator geometry and title and so on go here
creator.grab_set() # keep window on top
if __name__ == '__main__':
root.mainloop()
I have a Windows-10 PyGTK3 app (python 3.8 + GTK3.24) structured as follows: it has a non-modal main window, which opens a modal dialog (A), which in turn opens another modal dialog (B).
I use glade for the layout and properties of all three windows.
On the app startup I retain the instance of the GtkWindow A as follows:
def __init__(self):
self._main_window = builder.get_object("main_window")
...
def on_clicked_open_dialog_a(self, _widget):
dlg_a = DialogA(self._main_window)
dlg_a.run()
In the dialog A, I do a similar thing:
def __init__(self, parent):
self._dialog = builder.get_object("dialog_a")
self._dialog.set_transient_for(parent)
...
def on_clicked_open_dialog_b(self, _widget):
dlg_b = DialogB(self._dialog)
dlg_b.run()
And the same thing in the dialog B:
def __init__(self, parent):
self._dialog = builder.get_object("dialog_b")
self._dialog.set_transient_for(parent)
This is what it is supposed to look like
The problem that I am running into is that once I open the Dialog B from the Dialog A, the Dialog A ceases to behave like a proper modal dialog: if I click it, its window becomes active, even though the Dialog B is still displayed on top of it (and it can be moved and maximized/minimized, but not closed),
like so
and if I cover the app with another window and use Alt-Tab to bring the app back, the Dialog A comes on top, and I can only access the Dialog B by clicking on the Dialog A
as appears on this diagram
What am I doing wrong, and how do I fix it, please?
I am opening other windows from a single tkinter button as shown here:
https://www.pythontutorial.net/tkinter/tkinter-toplevel/
The code shown there is
import tkinter as tk
from tkinter import ttk
class Window(tk.Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.geometry('300x100')
self.title('Toplevel Window')
ttk.Button(self,
text='Close',
command=self.destroy).pack(expand=True)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x200')
self.title('Main Window')
# place a button on the root window
ttk.Button(self,
text='Open a window',
command=self.open_window).pack(expand=True)
def open_window(self):
window = Window(self)
window.grab_set()
if __name__ == "__main__":
app = App()
app.mainloop()
If I run this program, it is not possible to hit the "Open a window" button twice to get two Toplevel instances. I would like to get as many instances as I like to with only one button. Is this possible somehow?
Consider this line of code:
window.grab_set()
This is setting a grab on the first window that is created. That means that all events from both the keyboard and the mouse are funneled to the first window that is created. That means you can no longer click on the button in the root window until the grab has been removed. Note that if the window is destroyed, the grab is automatically removed.
Grabs are typically used when creating a modal dialog -- a dialog which requires user input before the program can continue. By doing a grab, you insure that the user can't interact with the main program until they've interacted with the dialog.
The solution is simple: remove the call to window.grab_set() if your goal is to be able to open multiple windows which can all be used at the same time.
Simply remove window.grab_set(). The grab_set() method routes all events for this application to this widget. Whatever events generated like button-click or keypress is directed to another window.
def open_window(self):
window = Window(self)
I'm having trouble figuring out how to close a python tkinter window menu when clicking on the root of the menu, ie."File".
I was hoping there was just a command option available when instantiating the menu but it appears as though that is not the case. Also I know that there is an unpost method I can use to get rid of the menu but I don't know how I would trigger it on root menu click.
Edit:
Since Bryan said that my menus should be acting the same as any other menus in my os I decided to put together an example of how I'm doing menus. Maybe I am doing something wrong here but on ubuntu in every other program if I click on the root of the menu it will close it again. In this program it does not close when clicking on the root, only when clicking elsewhere on the screen does the menu close.
import tkinter as tk
import tkinter.messagebox
class App(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.title("App Here")
self.window_menu = tk.Menu(self)
self.filemenu = tk.Menu(self.window_menu, tearoff=0)
self.build_window_menu()
self.config(menu=self.window_menu)
def build_window_menu(self):
self.window_menu.add_cascade(label="File", menu=self.filemenu)
self.filemenu.add_command(label='alert', command=self._handle_menualert)
def _handle_menualert(self):
tk.messagebox.showwarning(
"Menu Stuff",
"I am menu alert!"
)
if __name__ == '__main__':
app = App()
app.mainloop()
The gtk FileChooserWidget shows a context menu on right-click with "add to bookmarks", "show hidden files", and "show size column" options. I would like to override this menu with a custom menu.
Creating a menu on right-click from other gtk widgets (window, eventbox) is easy and there are a lot of tutorials out there showing how to do it.
I can't seem to get events from a gtk filechooser widget, however. The "on_button_press_event" callback in the following code never gets called:
#!/usr/bin/env python
import gtk
class file_chooser_test():
def __init__(self):
window = gtk.Window()
window.connect("delete_event", lambda w,e: gtk.main_quit())
chooser = gtk.FileChooserWidget()
chooser.set_size_request(600, 400)
chooser.add_events(gtk.gdk.BUTTON_PRESS_MASK)
chooser.connect("button-press-event", self.on_button_press_event)
window.add(chooser)
window.show_all()
gtk.main()
def on_button_press_event(self, widget, event=None):
print "event is: ", event
if __name__ == "__main__":
test = file_chooser_test()
Can anyone shed any light on how to override the default right-click menu on the GTK FileChooserWidget?
Thanks!