Increase tkSimpleDialog window size - python

How do i increase or define window size of tkSimpleDialog box ?
import Tkinter, tkSimpleDialog
root = Tkinter.Tk()
root.withdraw()
test = tkSimpleDialog.askstring("testing", "Enter your search string text")
print test

Make the second parameter as big as you like:
import Tkinter, tkSimpleDialog
root = Tkinter.Tk()
root.withdraw()
test = tkSimpleDialog.askstring("testing", "Enter your search string text in the space provided")
print test

Starting from: http://effbot.org/tkinterbook/tkinter-dialog-windows.htm
I did the following:
import Tkinter as tk, tkSimpleDialog
class MyDialog(tkSimpleDialog.Dialog):
def body(self, master):
self.geometry("800x600")
tk.Label(master, text="Enter your search string text:").grid(row=0)
self.e1 = tk.Entry(master)
self.e1.grid(row=0, column=1)
return self.e1 # initial focus
def apply(self):
first = self.e1.get()
self.result = first
root = tk.Tk()
root.withdraw()
test = MyDialog(root, "testing")
print test.result
If you want geometry and the label's text to be customizable, you will probably need to override __init__ (the version given in the link should be a good starting point).

If you want to wider box you can make buttons wider from the source code or override it inside your code:
def buttonbox(self):
'''add standard button box.
override if you do not want the standard buttons
'''
box = Frame(self)
w = Button(box, text="OK", width=100, command=self.ok, default=ACTIVE)
w.pack(side=LEFT, padx=5, pady=5)
w = Button(box, text="Cancel", width=100, command=self.cancel)
w.pack(side=LEFT, padx=5, pady=5)
self.bind("<Return>", self.ok)
self.bind("<Escape>", self.cancel)
box.pack()

tkSimpleDialog doesn't allows you to change it's geometry
In place use Tk() only
Here you have an exmple where you'll see the difference between two windows
import Tkinter, tkSimpleDialog
root = Tkinter.Tk()
root.geometry('240x850+200+100')
#root.withdraw()
test = tkSimpleDialog.askstring("testing", "Enter your search string text")
root.mainloop()
print test

Related

How to change focus of simpledialog in Tkinter?

I have several simpledialog popup windows. The first one that shows is in focus and after it closes then every single one after that is not in focus. The simpledialog code is this:
from tkinter import *
from tkinter import messagebox
import os
import tkinter as tk
from tkinter import simpledialog
def doing_stocks():
name = myaskstring("Input data", "Enter box number:", parent = root)
name2 = myaskstring("Input data2", "Enter box number2:", parent = root)
name3 = myaskstring("Input data3", "Enter box number3:", parent = root)
class My_QueryString(tk.simpledialog._QueryString):
def body(self, master):
self.bind('<KP_Enter>', self.ok)
self.bind('<Return>', self.ok)
w = Label(master, text=self.prompt, justify=LEFT)
w.grid(row=0, padx=5, sticky=W)
self.entry = Entry(master, name="entry")
self.entry.grid(row=1, padx=5, sticky=W+E)
if self.initialvalue is not None:
self.entry.insert(0, self.initialvalue)
self.entry.select_range(0, END)
root.update_idletasks()
self.entry.focus_force()
return self.entry
def myaskstring(title, prompt, **kw):
d = My_QueryString(title, prompt, **kw)
root.update_idletasks()
answer = d.result
d.destroy()
return answer
root = Tk()
root.geometry("700x761")
label1 = Label(root, text="")
label1.place(x = 0, y = 0)
button2 = Button(root, text = "Doing Stocks", command=doing_stocks).place(x = 300, y = 340)
root.mainloop()
This is a simplified version of the code. I call my simpledialog popups like this:
myaskstring("Title", "Prompt", parent = root)
In the doing_stocks() method the first time I call myaskstring the window and the entry field will be in focus then all times after that it won't be. How can I make every simpledialog be in focus when it appears on the screen?
I agree is seems odd that the focus isn't set to each My_QueryString instance when it's initialized. Regardless of the reason why, a workaround for it not happening is to bind a <Map> event handler function to the dialog's Entry widget to shift keyboard focus to itself whenever it's made visible.
The code below shows an implementation doing that. It's based on your code with the important changes indicated with # ALL CAP comments to make them stand out.
import tkinter as tk
from tkinter import simpledialog
from tkinter.constants import *
def doing_stocks():
name = myaskstring("Input data", "Enter box number:", parent=root)
name2 = myaskstring("Input data2", "Enter box number2:", parent=root)
name3 = myaskstring("Input data3", "Enter box number3:", parent=root)
class My_QueryString(tk.simpledialog._QueryString):
def body(self, master):
self.bind('<KP_Enter>', self.ok)
self.bind('<Return>', self.ok)
w = tk.Label(master, text=self.prompt, justify=LEFT)
w.grid(row=0, padx=5, sticky=W)
self.entry = tk.Entry(master, name="entry")
self.entry.grid(row=1, padx=5, sticky=W+E)
self.entry.bind('<Map>', self.on_map) # <--- ADDED.
if self.initialvalue is not None:
self.entry.insert(0, self.initialvalue)
self.entry.select_range(0, END)
root.update_idletasks()
# self.entry.focus_force() # <--- NOT NEEDED.
return self.entry
# ADDED METHOD.
def on_map(self, event):
self.entry.focus_force()
def myaskstring(title, prompt, **kw):
d = My_QueryString(title, prompt, **kw)
root.update_idletasks()
answer = d.result
# d.destroy() # <--- NOT NEEDED.
return answer
root = tk.Tk()
root.geometry("700x761")
label1 = tk.Label(root, text="")
label1.place(x = 0, y = 0)
button2 = tk.Button(root, text = "Doing Stocks", command=doing_stocks)
button2.place(x = 300, y = 340)
root.mainloop()

Python Tkinter display the name with Hi in front of it

Hello I'm a few weeks into python and I'm now starting learning tkinter. The button should have the text Say hello and when the user clicks the button, the bottom label should display the name with Hi in front of it. However I cannot get the label to display "Hi {name}". Could someone help me?
from tkinter import *
from tkinter.ttk import *
def process_name():
"""Do something with the name (in this case just print it)"""
global name_entry
print("Hi {}".format(name.get()))
def main():
"""Set up the GUI and run it"""
global name_entry
window = Tk()
name_label = Label(window, text='Enter name a name below:')
name_label.grid(row=0, column=0)
name_entry = Entry(window)
name_entry.grid(row=1, column=3)
button = Button(window, text='Say hello', command=process_name, padding=10)
button.grid(row=1, column=0, columnspan=2)
window.mainloop()
main()
I've tried using set() but it doesn't display.
Thank you.
This should work for your needs. Make sure to read the code comments to understand what I did properly.
Few points though,
Not recommended to use wildcard import like from tkinter import * . The reason is simple. both tkinter and tkinter.ttk have common classes and functions like Button, Label and more. It becomes ambiguous for interpreter to decide which ones to use.
use .config() or .configure() to update labels, buttons, entries or text widgets in tkinter. Like I did in code below.
Your code modified
from tkinter import *
from tkinter.ttk import *
def process_name():
"""Do something with the name (in this case just print it)"""
global name_entry # this will print hi {name} to terminal.
print("Hi {}".format(name_entry.get()))
global nameLabel # to change'the label with hi{name} text below the button.
nameLabel.configure(text=f'Hi {name_entry.get()}')
def main():
"""Set up the GUI and run it"""
global name_entry, nameLabel
window = Tk()
name_label = Label(window, text='Enter name a name below:')
name_label.grid(row=0, column=0)
name_entry = Entry(window)
name_entry.grid(row=1, column=3)
button = Button(window, text='Say hello', command=process_name, padding=10)
button.grid(row=1, column=0, columnspan=2)
# I defined a label BELOW the button to show how to change
nameLabel = Label(window, text=' ') # an empty text Label
nameLabel.grid(row=2)
window.mainloop()
main()

How to compulsory close message box for Toplevel window

image for that
I have few lines of code here which is login system which works fine but i can click on the Toplevel button multiple times when i provide the wrong password without closing the messagebox.How can i make it so that it has to be closed messagebox before i can make attempt again.
from tkinter import *
from tkinter import messagebox
def top():
if entry1.get() == "333":
log.destroy()
root.deiconify()
else:
messagebox.showerror("error", "try again")
root = Tk()
root.geometry("300x300")
log = Toplevel(root)
log.geometry("200x200")
label1 = Label(log, text="password")
entry1 = Entry(log)
button1 = Button(log, text="login", command=top)
label1.pack()
entry1.pack()
button1.pack(side="bottom")
lab = Label(root, text="welcome bro").pack()
root.withdraw()
root.mainloop()
You need to make the log window the parent of the dialog:
messagebox.showerror("error", "try again", parent=log)
By default it will use the root window (the Tk instance) as the parent which in this case is not what you want.
With hint from #furas this how to implement this:
create another function to the call it when the entry doesn't match and use grab_set method for the Toplevel window tp.grab_set().You can add your customarised image to the Toplevel window as well as message to display in the box(here: i use label to depict that)
from tkinter import *
from tkinter import messagebox
def dialog(): # this function to call when entry doesn't match
tp = Toplevel(log)
tp.geometry("300x100")
tp.title('error')
tp.grab_set() # to bring the focus to the window for you to close it
tp.resizable(width=False, height=False)
l = Label(tp, text="try again\n\n\n\n add your customarize image to the window")
l.pack()
def top():
if entry1.get() == "333":
log.destroy()
root.deiconify()
else:
dialog() # being called here
root = Tk()
root.geometry("300x300")
log = Toplevel(root)
log.geometry("200x200")
label1 = Label(log, text="password")
entry1 = Entry(log)
button1 = Button(log, text="login", command=top)
label1.pack()
entry1.pack()
button1.pack(side="bottom")
lab = Label(root, text="welcome bro").pack()
root.withdraw()
root.mainloop()

Tkinter: Tracing the state of a widget

I am aware that it is possible to trace the changes of, say, the entered value in an Entry widget by using e.g. a StringVar and a variable observer like Trace. Is it possible to also trace the state of a widget? Let's say we have the code:
from tkinter import *
class My_Window:
def __init__(self, root):
self.button1 = Button(root, text="Enter", command = self.disable_entrybox)
self.get_info_box1 = Entry(root)
self.button2 = Button(root, text="Enter", command = self.disable_entrybox)
self.get_info_box2 = Entry(root)
self.button1.pack()
self.get_info_box1.pack()
self.button2.pack()
self.get_info_box2.pack()
self.get_info_box2.config(state="disable")
def disable_entrybox(self):
x = self.get_info_box1.get()
self.get_info_box1.config(state="disable")
root = Tk()
my_window = My_Window(root)
root.mainloop()
And I want to trace if get_info_box1is disabled or not, and if it's disabled, change the state of get_info_box2 to "normal". Is there any way to do this?

How to control the tkinter combobox selection highlighting

I wrote a small farad converter to learn GUI programming. It works great, looks fine-ish. The only problem is I can't seem to figure out how to control this strange highlighting that comes up on my ttk.Combobox selections. I did use a ttk.Style(), but it only changed the colors of the ttk.Combobox background, entries, etc. I also tried changing openbox/gtk themes.
I'm talking about what's seen there on the text "microfarads (uF)".
It'd be fine, if it highlighted the entire box; but I'd rather have it gone completely.
How can I manipulate a ttk.Combobox's selection highlight?
# what the farad?
# thomas kirkpatrick (jtkiv)
from tkinter import *
from tkinter import ttk
# ze la programma.
def conversion(*args):
# this is the numerical value
inV = float(inValue.get())
# these two are the unit (farads, microfarads, etc.) values
inU = inUnitsValue.current()
outU = outUnitsValue.current()
# "mltplr" is multiplied times inValue (inV)
if inU == outU:
mltplr = 1
else:
mltplr = 10**((outU - inU)*3)
outValue.set(inV*mltplr)
# start of GUI code
root = Tk()
root.title("What the Farad?")
# frame
mainFrame = ttk.Frame(root, width="364", padding="4 4 8 8")
mainFrame.grid(column=0, row=0)
# input entry
inValue = StringVar()
inValueEntry = ttk.Entry(mainFrame, width="20", justify="right", textvariable=inValue)
inValueEntry.grid(column=1, row=1, sticky="W")
# input unit combobox
inUnitsValue = ttk.Combobox(mainFrame)
inUnitsValue['values'] = ('kilofarads (kF)', 'farads (F)', 'millifarads (mF)', 'microfarads (uF)', 'nanofarads (nF)', 'picofarads (pF)')
inUnitsValue.grid(column=2, row=1, sticky="e")
inUnitsValue.state(['readonly'])
inUnitsValue.bind('<<ComboboxSelected>>', conversion)
# result label
outValue = StringVar()
resultLabel = ttk.Label(mainFrame, textvariable=outValue)
resultLabel.grid(column=1, row=2, sticky="e")
# output unit combobox
outUnitsValue = ttk.Combobox(mainFrame)
outUnitsValue['values'] = ('kilofarads (kF)', 'farads (F)', 'millifarads (mF)', 'microfarads (uF)', 'nanofarads (nF)', 'picofarads (pF)')
outUnitsValue.grid(column=2, row=2, sticky="e")
outUnitsValue.state(['readonly'])
outUnitsValue.bind('<<ComboboxSelected>>', conversion)
# padding for widgets
for child in mainFrame.winfo_children(): child.grid_configure(padx=4, pady=4)
# focus
inValueEntry.focus()
# bind keys to convert (auto-update, no button)
root.bind('<KeyRelease>', conversion)
root.mainloop()
Could it be that with a readonly combobox the problem is not the selection but the relatively strong focus-indicator?
With this workarround you lose the ability to control your program by keyboard. To do it right you would have to change the style of the focus-highlighting.
from tkinter import *
from ttk import *
def defocus(event):
event.widget.master.focus_set()
root = Tk()
comboBox = Combobox(root, state="readonly", values=("a", "b", "c"))
comboBox.grid()
comboBox.set("a")
comboBox.bind("<FocusIn>", defocus)
mainloop()
You can use the Combobox's selection_clear() method to clear the selection whenever you want.
e.g
inUnitsValue.selection_clear()
Just refresh the selected value of the Combobox.
This will help for removing the highlight.
import tkinter.ttk
import tkinter
items = ["test1","test2","test3","test4"]
class TkCombobox(tkinter.ttk.Combobox):
def __init__(self, *arg, **kwarg):
super(TkCombobox, self).__init__(*arg, **kwarg)
self._strvar_ = tkinter.StringVar()
self._strvar_.set("")
self["textvariable"] = self._strvar_
self.bind("<<ComboboxSelected>>", self.highlight_clear)
def highlight_clear(self, event):
current = self._strvar_.get()
self.set("")
self.set(current)
master = tkinter.Tk();master.geometry("400x400")
c = TkCombobox(master, values=items, state="readonly")
c.pack()
master.mainloop()

Categories