Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Using the <a href="http://docs.python.org/2/reference/simple_stmts.html#the-global-statement" rel="nofollow noreferrer">global statement</a> is unnecessary in the two scenarios that come to mind. </p> <ol> <li>you want to code a dialog box that can be imported to use <strong>with</strong> a main GUI</li> <li>you want to code a dialog box that can be imported to use <strong>without</strong> a main GUI</li> </ol> <hr> <h1>code a dialog box that can be imported to use <strong>with</strong> a main GUI</h1> <hr> <p>Avoiding the global statement can be accomplished by passing a dictionary &amp; key when you create an instance of a dialog box. The dictionary &amp; key can then be associated with the button's command, by using <a href="https://docs.python.org/3.3/tutorial/controlflow.html?highlight=lambda#lambda-expressions" rel="nofollow noreferrer">lambda</a>. That creates an anonymous function that will execute your function call (with args) when the button is pressed.</p> <p>You can avoid the need to pass the parent every time you create an instance of the dialog box by binding the parent to a class attribute (root in this example). </p> <p>You can save the following as <code>mbox.py</code> in <code>your_python_folder\Lib\site-packages</code> or in the same folder as your main GUI's file.</p> <pre><code>import tkinter class Mbox(object): root = None def __init__(self, msg, dict_key=None): """ msg = &lt;str&gt; the message to be displayed dict_key = &lt;sequence&gt; (dictionary, key) to associate with user input (providing a sequence for dict_key creates an entry for user input) """ tki = tkinter self.top = tki.Toplevel(Mbox.root) frm = tki.Frame(self.top, borderwidth=4, relief='ridge') frm.pack(fill='both', expand=True) label = tki.Label(frm, text=msg) label.pack(padx=4, pady=4) caller_wants_an_entry = dict_key is not None if caller_wants_an_entry: self.entry = tki.Entry(frm) self.entry.pack(pady=4) b_submit = tki.Button(frm, text='Submit') b_submit['command'] = lambda: self.entry_to_dict(dict_key) b_submit.pack() b_cancel = tki.Button(frm, text='Cancel') b_cancel['command'] = self.top.destroy b_cancel.pack(padx=4, pady=4) def entry_to_dict(self, dict_key): data = self.entry.get() if data: d, key = dict_key d[key] = data self.top.destroy() </code></pre> <p>You can see examples that subclass TopLevel and tkSimpleDialog (tkinter.simpledialog in py3) at <a href="http://effbot.org/tkinterbook/tkinter-dialog-windows.htm" rel="nofollow noreferrer">effbot</a>.</p> <p>It's worth noting that <a href="https://stackoverflow.com/a/15081982/1217270">ttk widgets</a> are interchangeable with the tkinter widgets in this example.</p> <p>To accurately center the dialog box read → <a href="https://stackoverflow.com/a/10018670/1217270">this</a>.</p> <p>Example of use:</p> <pre><code>import tkinter import mbox root = tkinter.Tk() Mbox = mbox.Mbox Mbox.root = root D = {'user':'Bob'} b_login = tkinter.Button(root, text='Log in') b_login['command'] = lambda: Mbox('Name?', (D, 'user')) b_login.pack() b_loggedin = tkinter.Button(root, text='Current User') b_loggedin['command'] = lambda: Mbox(D['user']) b_loggedin.pack() root.mainloop() </code></pre> <hr> <h1>code a dialog box that can be imported to use <em>without</em> a main GUI</h1> <hr> <p>Create a module containing a dialog box class (MessageBox here). Also, include a function that creates an instance of that class, and finally returns the value of the button pressed (or data from an Entry widget).</p> <p>Here is a complete module that you can customize with the help of these references: <a href="http://infohost.nmt.edu/tcc/help/pubs/tkinter/web/index.html" rel="nofollow noreferrer">NMTech</a> &amp; <a href="http://effbot.org/tkinterbook/tkinter-index.htm" rel="nofollow noreferrer">Effbot</a>.<br> Save the following code as <code>mbox.py</code> in <code>your_python_folder\Lib\site-packages</code></p> <pre><code>import tkinter class MessageBox(object): def __init__(self, msg, b1, b2, frame, t, entry): root = self.root = tkinter.Tk() root.title('Message') self.msg = str(msg) # ctrl+c to copy self.msg root.bind('&lt;Control-c&gt;', func=self.to_clip) # remove the outer frame if frame=False if not frame: root.overrideredirect(True) # default values for the buttons to return self.b1_return = True self.b2_return = False # if b1 or b2 is a tuple unpack into the button text &amp; return value if isinstance(b1, tuple): b1, self.b1_return = b1 if isinstance(b2, tuple): b2, self.b2_return = b2 # main frame frm_1 = tkinter.Frame(root) frm_1.pack(ipadx=2, ipady=2) # the message message = tkinter.Label(frm_1, text=self.msg) message.pack(padx=8, pady=8) # if entry=True create and set focus if entry: self.entry = tkinter.Entry(frm_1) self.entry.pack() self.entry.focus_set() # button frame frm_2 = tkinter.Frame(frm_1) frm_2.pack(padx=4, pady=4) # buttons btn_1 = tkinter.Button(frm_2, width=8, text=b1) btn_1['command'] = self.b1_action btn_1.pack(side='left') if not entry: btn_1.focus_set() btn_2 = tkinter.Button(frm_2, width=8, text=b2) btn_2['command'] = self.b2_action btn_2.pack(side='left') # the enter button will trigger the focused button's action btn_1.bind('&lt;KeyPress-Return&gt;', func=self.b1_action) btn_2.bind('&lt;KeyPress-Return&gt;', func=self.b2_action) # roughly center the box on screen # for accuracy see: https://stackoverflow.com/a/10018670/1217270 root.update_idletasks() xp = (root.winfo_screenwidth() // 2) - (root.winfo_width() // 2) yp = (root.winfo_screenheight() // 2) - (root.winfo_height() // 2) geom = (root.winfo_width(), root.winfo_height(), xp, yp) root.geometry('{0}x{1}+{2}+{3}'.format(*geom)) # call self.close_mod when the close button is pressed root.protocol("WM_DELETE_WINDOW", self.close_mod) # a trick to activate the window (on windows 7) root.deiconify() # if t is specified: call time_out after t seconds if t: root.after(int(t*1000), func=self.time_out) def b1_action(self, event=None): try: x = self.entry.get() except AttributeError: self.returning = self.b1_return self.root.quit() else: if x: self.returning = x self.root.quit() def b2_action(self, event=None): self.returning = self.b2_return self.root.quit() # remove this function and the call to protocol # then the close button will act normally def close_mod(self): pass def time_out(self): try: x = self.entry.get() except AttributeError: self.returning = None else: self.returning = x finally: self.root.quit() def to_clip(self, event=None): self.root.clipboard_clear() self.root.clipboard_append(self.msg) </code></pre> <p>and: </p> <pre><code>def mbox(msg, b1='OK', b2='Cancel', frame=True, t=False, entry=False): """Create an instance of MessageBox, and get data back from the user. msg = string to be displayed b1 = text for left button, or a tuple (&lt;text for button&gt;, &lt;to return on press&gt;) b2 = text for right button, or a tuple (&lt;text for button&gt;, &lt;to return on press&gt;) frame = include a standard outerframe: True or False t = time in seconds (int or float) until the msgbox automatically closes entry = include an entry widget that will have its contents returned: True or False """ msgbox = MessageBox(msg, b1, b2, frame, t, entry) msgbox.root.mainloop() # the function pauses here until the mainloop is quit msgbox.root.destroy() return msgbox.returning </code></pre> <p>After <em>mbox</em> creates an instance of <em>MessageBox</em> it starts the mainloop,<br> which effectively stops the function there until the mainloop is exited via <code>root.quit()</code>.<br> The <em>mbox</em> function can then access <code>msgbox.returning</code>, and return its value. </p> <p>Example:</p> <pre><code>user = {} mbox('starting in 1 second...', t=1) user['name'] = mbox('name?', entry=True) if user['name']: user['sex'] = mbox('male or female?', ('male', 'm'), ('female', 'f')) mbox(user, frame=False) </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload