Python Tkinter. Cant apply theme for second window of program - python

I am trying to make basic gui with Tkinter. But the default theme "Motif" is not pretty so I`ve switched to "Clam". But the problem in second window of my program, it still uses default theme "Motif".
Let me show at first my code:
from Tkinter import *
from ttk import *
def label(row, column, text):
L = Label(root, text=text, anchor='w')
L.grid(row=row,column=column,sticky="nw",pady=2,padx=3)
def button(root, row, column, text, command):
B = Button(root, text=text, command=command, width=15)
B.grid(row=row, column=column, sticky="e", pady=4, padx=3)
def entry(row, column, insert="", show=""):
E = Entry(root, width=32)
E.insert(0, insert)
E.config(show=show)
E.grid(row=row,column=column)
return E
def show_ldif():
values_list = []
givenname = var0.get()
sn = var1.get()
country = var2.get()
location = var3.get()
skype = var8.get()
cn = givenname[0].lower() + sn.lower()
email = cn + "#company.com"
# ldif is import format for openLDAP
ldif_list =[]
ldif_list.append(("dn: cn=%s,cn=people,ou=company,dc=company,dc=com\n") % cn)
ldif_list.append('c: %s\n'% country)
ldif_list.append('cn: %s\n'% cn)
ldif_list.append(('objectclass: inetOrgPerson\n'
'objectclass: posixAccount\n'
'objectclass: top\n'
'objectclass: shadowAccount\n'
'objectclass: ldapPublicKey\n'
'objectclass: extensibleObject\n'))
ldif = ''.join(ldif_list)
root2 = Tk()
root2.title("Result")
root2.style = Style()
root2.style.theme_use("clam")
ldif_text = Text(root2, height=30, width=50)
ldif_text.insert(END, ldif)
ldif_text.grid(row=0,column=0,columnspan = 2)
button(root2, 1, 1, "Copy to Clipboard", yes_no)
button(root2, 1, 0, "Import to LDAP", yes_no)
def yes_no():
pass
root = Tk()
root.style = Style()
root.style.theme_use("clam")
root.title("LDAP Adder")
label(0, 0, 'First name')
var0 = entry(0, 1)
label(1, 0, 'Second name')
var1 = entry(1, 1)
label(2, 0, 'Country (two letters)')
var2 = entry(2, 1)
label(3, 0, 'City')
var3 = entry(3, 1)
label(8, 0, 'Skype')
var8 = entry(8, 1)
label(13, 0, '')
button(root, 14, 0, 'Show', show_ldif)
button(root, 14, 1, 'Quit', root.quit)
root.mainloop()
First window looks well:
It is Calm theme for Tkinter. Then I can click on button 'Show' and second window 'Result' will appear:
But second one still uses default theme (look at buttons of right window). But why? I`ve activated "Calm" theme for second window:
root2 = Tk()
root2.title("Result")
root2.style = Style()
root2.style.theme_use("clam")

This is because you are creating two instances of Tk. That is not how tkinter is designed to be used. You must create exactly one instance of Tk. If you need additional windows, create instances of Toplevel.

With such code looks good:
from Tkinter import *
from ttk import *
def label(row, column, text):
L = Label(root, text=text, anchor='w')
L.grid(row=row,column=column,sticky="nw",pady=2,padx=3)
def button(root, row, column, text, command):
B = Button(root, text=text, command=command, width=15)
B.grid(row=row, column=column, sticky="e", pady=4, padx=3)
def entry(row, column, insert="", show=""):
E = Entry(root, width=32)
E.insert(0, insert)
E.config(show=show)
E.grid(row=row,column=column)
return E
def show_ldif():
values_list = []
givenname = var0.get()
sn = var1.get()
country = var2.get()
location = var3.get()
skype = var8.get()
cn = givenname[0].lower() + sn.lower()
email = cn + "#company.com"
# ldif is import format for openLDAP
ldif_list =[]
ldif_list.append(("dn: cn=%s,cn=people,ou=company,dc=company,dc=com\n") % cn)
ldif_list.append('c: %s\n'% country)
ldif_list.append('cn: %s\n'% cn)
ldif_list.append(('objectclass: inetOrgPerson\n'
'objectclass: posixAccount\n'
'objectclass: top\n'
'objectclass: shadowAccount\n'
'objectclass: ldapPublicKey\n'
'objectclass: extensibleObject\n'))
ldif = ''.join(ldif_list)
top = Toplevel()
top.title("Result")
ldif_text = Text(top, height=30, width=50)
ldif_text.insert(END, ldif)
ldif_text.grid(row=0,column=0,columnspan = 2)
button(top, 1, 1, "Copy to Clipboard", yes_no)
button(top, 1, 0, "Import to LDAP", yes_no)
def yes_no():
pass
root = Tk()
root.style = Style()
root.style.theme_use("clam")
root.title("LDAP Adder")
label(0, 0, 'First name')
var0 = entry(0, 1)
label(1, 0, 'Second name')
var1 = entry(1, 1)
label(2, 0, 'Country (two letters)')
var2 = entry(2, 1)
label(3, 0, 'City')
var3 = entry(3, 1)
label(8, 0, 'Skype')
var8 = entry(8, 1)
label(13, 0, '')
button(root, 14, 0, 'Show', show_ldif)
button(root, 14, 1, 'Quit', root.quit)
root.mainloop()
So before I have been creating new window with:
root2 = Tk()
root2.title("Result")
root2.style = Style()
root2.style.theme_use("clam")
And theme cant be applied. With #Rinzler help I changed this code to:
top = Toplevel()
top.title("Result")
And activated theme only once in the beginning.

Related

Getting error when trying to create tkinter frame?

I'm trying to understand the following example below:
import sys
from tkinter import *
def btn():
login_frame.destroy()
home_frame = home()
home_frame.pack(fill="both", expand=True)
def btn2():
home_frame.destroy()
#home_frame = home()
#home_frame.pack(fill="both", expand=True)
def login():
frame = Frame(root)
Label(frame, text = "test1").grid(row = 0)
Label(frame, text = "test2").grid(row = 1)
Label(frame, text = "test3").grid(row = 2)
e1 = Entry(frame)
e2 = Entry(frame)
e1.grid(row=1, column = 1)
e2.grid(row=2, column = 1)
Button(frame, text = 'btn1', command = btn).grid(row = 4, column = 0, sticky = W, pady = 4)
Button(frame, text = 'btn2', command = btn).grid(row = 4, column = 1, sticky = W, pady = 4)
return frame
def home():
frame = Frame(root)
Label(frame, text="Welcome").pack()
Button(frame, text = 'test', command = btn2).pack()
return frame
root = Tk()
root.wm_title('test')
login_frame = login()
login_frame.pack(fill="both", expand=True)
root.mainloop()
I create the first login_frame, and btn1 destroys it and creates home_frame right? but when I click the next btn I get the following error:
NameError: name 'home_frame' is not defined
Why isn't this frame defined? I thought it would have been defined when btn is pushed and home_frame = home() ?

How to get variable value from Entry tkinter python?

I am trying to create a GUI with tkinter. I was able to setup the interface, with buttons, labels etc. However, when I type a string or int in the interface (using Entry, but also with combobox and chekcbutton) the assigned varible doesn't appear if try to print it, I only got printed the following instead of the variable values:
.!entry, .!entry2, .!combobox, .!checkbutton
Does anybody know how to fix it?
from tkinter import *
from tkinter.ttk import Combobox
from tkinter import filedialog
def browse_button1():
global folder_path
filename = filedialog.askdirectory()
folder_path1.set(filename)
def browse_button2():
global folder_path
filename = filedialog.askdirectory()
folder_path2.set(filename)
main_window = Tk()
folder_path1 = StringVar()
folder_path2 = StringVar()
var = StringVar()
def1 = StringVar(main_window, value='Sharp')
# Labels
Label(main_window, text= "Folder Path").grid(row = 0, column = 0)
Label(main_window, text= "Scan File").grid(row = 1, column = 0)
#Text Input
e1 = Entry(main_window, width= 50, borderwidth= 5, textvariable= folder_path1)
e1.grid(row= 0, column= 1, columnspan= 2, sticky="we", pady=10)
e2 = Entry(main_window, width= 50, borderwidth= 5, textvariable= folder_path2)
e2.grid(row= 1, column= 1, columnspan= 2, sticky="we", pady=10)
#Combobox list
var.set("Sharp")
data = ("Sharp", "Intermediate", "Standard", "Soft")
cb = Combobox(main_window, values=data, textvariable= def1)
cb.grid(row=4, column= 1, sticky = 'w', pady=10)
#Checkbutton
cbu = Checkbutton(main_window)
cbu.grid(row=6, column=1, sticky = 'w', pady=10)
def on_click():
print(f"{e1}, {e2}, {cb}, {cbu}")
#Buttons
Button(main_window, text= "Run", command = on_click, width = 25).grid(row= 8, column= 1, columnspan= 2, sticky="we", pady=10)
Button(main_window, text= "Browse", command = browse_button1, width = 12).grid(row= 0, column= 3)
Button(main_window, text= "Browse", command = browse_button2, width = 12).grid(row= 1, column= 3)
main_window.mainloop()
Use the .get() method to retrieve widget values. Simply change:
def on_click():
print(f"{e1}, {e2}, {cb}, {cbu}")
to:
# create a variable to store the Checkbutton state
cb_var = StringVar()
# update 'cbu' to use that variable
cbu = Checkbutton(main_window, variable=cb_var)
def on_click():
print(f"{e1.get()}, {e2.get()}, {cb.get()}, {cb_var.get()}")

Making executable cx_freeze with pywin32 code = error no module named win32

So I have this PDF printer code (the code runs from console perfectly) and I wanted to make it executable .exe.
I tried with Python 3.8.2, cx_freeze, by issuing the cxfreeze-quickstart.exe command. Filling basic data, and selecting (G) as GUI option. All went well and got the program pdfprinter.exe, but when I try to run it on Windows 10, i get error message "no module named win32".
Can someone help how to make an executable from this code?
Error message picture
import win32api
import win32print
import traceback
from tkinter.filedialog import askopenfilename
from tkinter import *
from tkinter import font # * doesn't import font or messagebox
from tkinter import messagebox
root = Tk()
root.title("Python Printer")
root.geometry("410x310")
root.resizable(False, False)
root.tk.call('encoding', 'system', 'utf-8')
def font_size(fs):
return font.Font(family='Helvetica', size=fs, weight='bold')
# Add a grid
mainframe = Frame(root)
#mainframe.grid(column=0,row=0, sticky=(N,W,E,S) )
mainframe.grid(column=0,row=0, sticky=(N) )
mainframe.columnconfigure(0, weight = 1)
mainframe.rowconfigure(0, weight = 1)
mainframe.pack(pady = 10, padx = 0)
# Create a _printer variable
_printer = StringVar(root)
# Create a _color variable
_color = StringVar(root)
_filename = ""
# on change dropdown value
def sel_printer(*args):
print( _printer.get() )
# link function to change dropdown
_printer.trace('w', sel_printer)
def sel_color(*args):
print( _color.get() )
# link function to change dropdown
_color.trace('w', sel_color)
def UploadAction(event=None):
global _filename
_filename = filedialog.askopenfilename()
#print('Selected:', _filename)
def PrintAction(event=None):
PRINTER_DEFAULTS = {"DesiredAccess":win32print.PRINTER_ALL_ACCESS}
pHandle = win32print.OpenPrinter(_printer.get(), PRINTER_DEFAULTS)
properties = win32print.GetPrinter(pHandle, 2)
properties['pDevMode'].Color = 1 if str(_color.get()) == "Color" else 2
properties['pDevMode'].Copies = 1
win32print.SetPrinter(pHandle, 2, properties, 0)
if not _filename:
messagebox.showerror("Error", "No File Selected")
return
elif not _printer.get():
messagebox.showerror("Error", "No Printer Selected")
return
try:
#win32print.SetDefaultPrinter(_printer.get())
win32api.ShellExecute(0, "print", _filename, None, ".", 0)
win32print.ClosePrinter(pHandle)
except:
pass
messagebox.showerror("Error", "There was an error printing the file :(")
choices = [printer[2] for printer in win32print.EnumPrinters(2)]
_printer.set(win32print.GetDefaultPrinter()) # set the default option
popupMenu = OptionMenu(mainframe, _printer, *choices)
popupMenu['font'] = font_size(12)
Label(mainframe, text="SELECT PRINTER").grid(row = 1, column = 1)
popupMenu.grid(row = 2, column =1)
# Dictionary with options
choices = ["COLOR", "MONOCHROME"]
_color.set("COLOR") # set the default option
popupMenu2 = OptionMenu(mainframe, _color, *choices)
popupMenu2['font'] = font_size(12)
Label(mainframe, text="COLOR MODE").grid(row = 3, column = 1)
popupMenu2.grid(row = 4, column =1)
Label(mainframe, text="SELECT FILE").grid(row = 5, column = 1)
button = Button(mainframe, text=u"\uD83D\uDCC1" ' BROWSE', command=UploadAction)
button['font'] = font_size(12)
button.grid(row = 6, column =1)
_copies = IntVar()
_copies.set(1)
def copies_increase(event=None):
_copies.set(_copies.get() + 1)
def copies_decrease(event=None):
_copies.set(_copies.get() - 1)
if _copies.get() < 1 :
_copies.set(1)
Label(mainframe, textvariable=_copies).grid(columnspan=2)
button_frame = Frame(mainframe)
button_frame.grid(columnspan=2)
dec_button = Button(button_frame, text=u"\u2212", command=copies_decrease, fg="dark green", bg = "white", height=1, width=3 )
dec_button['font'] = font_size(10)
inc_button = Button(button_frame, text=u"\uFF0B", command=copies_increase, fg="dark green", bg = "white", height=1, width=3 )
inc_button['font'] = font_size(10)
button_frame.columnconfigure(0, weight=1)
button_frame.columnconfigure(1, weight=1)
dec_button.grid(row=0, column=0, sticky=W+E)
inc_button.grid(row=0, column=1, sticky=W+E)
Label(mainframe).grid(row = 10, column = 1)
p_button = Button(mainframe, text=u'\uD83D\uDDB6' + " PRINT", command=PrintAction, fg="dark green", bg = "white")
p_button['font'] = font_size(18)
p_button.grid(row = 11, column =1)
root.mainloop()

how can I get the value of Entry Widget when the related class is called after login class

I'm trying to make a login window. I found a good example code here in Stackoverflow and added it with a simple code using Entry widget. After log in successfully, however, I can't get correct values of textvariable of Entry Widget even though I try to get them with Entry's instance.get().
I've tried many ways I could do. But, I can't find what's wrong.
I'm working with python 2.7. please help.
from Tkinter import *
import tkMessageBox as tm
class LoginFrame:
def __init__(self):
root = Tk()
self.label_1 = Label(root, text="Username")
self.label_2 = Label(root, text="Password")
self.entry_1 = Entry(root)
self.entry_2 = Entry(root, show="*")
self.label_1.grid(row=0, sticky=E)
self.label_2.grid(row=1, sticky=E)
self.entry_1.grid(row=0, column=1)
self.entry_2.grid(row=1, column=1)
self.checkbox = Checkbutton(root, text="Keep me logged in")
self.checkbox.grid(columnspan=2)
self.logbtn = Button(root, text="Login", command =
self._login_btn_clickked)
self.logbtn.grid(columnspan=2)
root.mainloop()
def _login_btn_clickked(self):
username = self.entry_1.get()
password = self.entry_2.get()
#print(username, password)
if username == "1" and password == "1":
#tm.showinfo("Login info", "Welcome John")
app = EntrySample()
app.window.mainloop()
else:
tm.showerror("Login error", "Incorrect username")
class EntrySample:
def __init__(self):
self.window = Tk()
self.window.title("Test Entry")
Label(self.window, text = "Kor").grid(row = 1,
column = 1, sticky = W)
self.kor = IntVar()
self.enKor = Entry(self.window, textvariable = self.kor,
justify = RIGHT).grid(row = 1, column = 2)
Label(self.window, text = "Eng").grid(row = 2,
column = 1, sticky = W)
self.eng = IntVar()
self.enEng = Entry(self.window, textvariable = self.eng,
justify = RIGHT).grid(row = 2, column = 2)
Label(self.window, text = "Math").grid(row = 3,
column = 1, sticky = W)
self.math = IntVar()
self.enMath = Entry(self.window, textvariable = self.math,
justify = RIGHT).grid(row = 3, column = 2)
btComputePayment = Button(self.window, text = "Calculate",
command = self.compute).grid(
row = 4, column = 2, sticky = E)
def compute(self):
total = self.kor.get()+self.eng.get()+self.math.get()
avg = total/3.0
print total
print '%3.2f' %avg
LoginFrame()

get previous Entry

I am trying to make a tkinter widget that will remember the previous entry. The problem I am having is the that the button method I made erases the previous entry every time its pressed.
from Tkinter import *
class step1():
def __init__(self):
pass
def getTextbook(self):
temp = str(textbook.get())
textbook.delete(0, END)
x = " "
x += temp
print x
def equal_button(self):
print getTextbook(self)
root = Tk()
root.title("step1")
root.geometry("600x600")
s = step1()
app = Frame(root)
app.grid()
label = Label(app, text = "step1")
label.grid()
textbook = Entry(app, justify=RIGHT)
textbook.grid(row=0, column = 0, columnspan = 3, pady = 5)
textbook2 = Entry(app, justify=RIGHT)
textbook2.grid(row=1, column = 0, columnspan = 3, pady = 5)
button1 = Button(app, text = "Return", command = lambda: s.getTextbook())
button1.grid()
button2 = Button(app, text="Equal")
button2.grid()
root.mainloop()
The variable X in your getTextbook() is being overwritten every time you set it to " ". Try a list instead, and append each entry to the list when the button is pressed:
from Tkinter import *
root = Tk()
textbookList = []
def getTextbook():
textbookList.append(textbook.get())
textbook.delete(0,END)
print textbookList
textbook = Entry(root)
textbook.pack()
btn1 = Button(root, text='Return', command=getTextbook)
btn1.pack()
root.mainloop()

Categories

Resources