I am new to python, the above figure is two UI, I was trying to insert the two tab from the right side UI into the left side UI. But I had met some error and no idea how to solve.
Now below is the original coding of the left side UI
import tkinter as tkk
from tkinter import *
from tkinter import messagebox
import os.path
import hashlib
import sys
import time
import getpass
from tkinter import filedialog
import platform
import getpass
import os,sys
import tkinter.font as font
from tkinter import ttk
from tkinter import StringVar
import Consts
import shutil
class Page(tkk.Frame):
def __init__(self, *args, **kwargs):
tkk.Frame.__init__(self, *args, **kwargs)
def show(self):
self.lift()
class Page1(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs,bg='white')
my_system=platform.uname()
#computer information
comsys=my_system.system
comnode=my_system.node
comrel=my_system.release
comver=my_system.version
commac=my_system.machine
compro=my_system.processor
comuser=getpass.getuser()
label1 = tkk.Label(self, text="System: "+comsys,bg='white')
label1.grid(row=1,column=1,pady=10,sticky='w')
label2 = tkk.Label(self, text="Computer Name: "+comnode,bg='white')
label2.grid(row=2,column=1,pady=10,sticky='w')
label3 = tkk.Label(self, text="Release: "+comrel,bg='white')
label3.grid(row=3,column=1,pady=10,sticky='w')
label4 = tkk.Label(self, text="Version: "+comver,bg='white')
label4.grid(row=4,column=1,pady=10,sticky='w')
label5 = tkk.Label(self, text="Machine: "+commac,bg='white')
label5.grid(row=5,column=1, pady=10,sticky='w')
label6 = tkk.Label(self, text="Processor: "+compro,bg='white')
label6.grid(row=6,column=1, pady=10,sticky='w')
label7 = tkk.Label(self, text="Username: "+comuser,bg='white')
label7.grid(row=7,column=1,pady=10,sticky='w')
#computer usage hold first, no idea how to do
class Page2(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs,bg='white')
tabControl=ttk.Notebook(self)
qsFrame = ttk.Frame(tabControl)
fsFrame = ttk.Frame(tabControl)
csFrame = ttk.Frame(tabControl)
#tab
tabControl.add(qsFrame, text='Quick Scan')
tabControl.add(fsFrame, text='Full Scan')
tabControl.add(csFrame, text='Custom Scan')
tabControl.pack(expand=1,fill="both")
class Page3(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs,bg='white')
label = tkk.Label(self, text="This is page 3")
label.grid(row=2,column=1)
def mytools():
total, used, free = shutil.disk_usage("/")
print("Total:%d GB" %(total // (2**30)))
print("Used:%d GB" %(used // (2**30)))
print("Free:%d GB" %(free // (2**30)))
if free <= total/2:
clean = os.popen('Cleanmgr.exe/ sagerun:1').read()
#print(clean)
def btn1():
if __name__ =="__main__":
mytools()
button1=ttk.Button(self,text="Clean Up",command=btn1)
button1.grid(row=3,column=2)
class Page4(Page):
def __init__(self, *args, **kwargs):
Page.__init__(self, *args, **kwargs,bg='white')
label = tkk.Label(self, text="This is page 4")
label.grid(row=2,column=1)
class MainView(tkk.Frame):
def __init__(self, *args, **kwargs):
tkk.Frame.__init__(self, *args, **kwargs)
p1 = Page1(self)
p2 = Page2(self)
p3 = Page3(self)
p4 = Page4(self)
buttonframe = tkk.Frame(self)
container = tkk.Frame(self,bg='white')
buttonframe.pack(side="left", fill="x", expand=False)
container.pack(side="left", fill="both", expand=True)
buttonframe.grid_rowconfigure(0,weight=1)
buttonframe.grid_columnconfigure(0,weight=1)
container.grid_rowconfigure(0,weight=1)
container.grid_columnconfigure(0,weight=1)
p1.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p2.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p3.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
p4.place(in_=container, x=0, y=0, relwidth=1, relheight=1)
stats_btn = tkk.PhotoImage(file='C:/FYP/SecuCOM2022/icon&pic/stats.png')
scanner_btn = tkk.PhotoImage(file='C:\FYP\SecuCOM2022\icon&pic\scanner.png')
speedup_btn = tkk.PhotoImage(file='C:\FYP\SecuCOM2022\icon&pic\speedup.png')
settings_btn = tkk.PhotoImage(file='C:\FYP\SecuCOM2022\icon&pic\settings.png')
#logo
logo=tkk.PhotoImage(file="C:\FYP\SecuCOM2022\icon&pic\g (1).png")
label=tkk.Label(buttonframe,image=logo)
label.grid(row=0,column=0, padx=10,pady=10)
logo.image = logo
b1 = tkk.Button(buttonframe, image=stats_btn, command=p1.show, borderwidth=0)
b2 = tkk.Button(buttonframe, image=scanner_btn, command=p2.show, borderwidth=0)
b3 = tkk.Button(buttonframe, image=speedup_btn, command=p3.show, borderwidth=0)
b4 = tkk.Button(buttonframe, image=settings_btn, command=p4.show, borderwidth=0)
b1.image = stats_btn
b2.image = scanner_btn
b3.image = speedup_btn
b4.image = settings_btn
b1.grid(row=1,column=0,padx=10,pady=10)
b2.grid(row=2,column=0,padx=10,pady=10)
b3.grid(row=3,column=0,padx=10,pady=10)
b4.grid(row=4,column=0,padx=10,pady=10)
if __name__ == "__main__":
root= Tk()
main = MainView(root)
main.pack(side="top", fill="both", expand=True)
main.grid_rowconfigure(0,weight=1)
main.grid_columnconfigure(0,weight=1)
root.title("SecuCOM2022")
root.geometry("600x300")
root.maxsize(600,375)
root.minsize(600,375)
root.iconbitmap('C:\FYP\SecuCOM2022\icon&pic\g.png')
root.mainloop()
root.mainloop()
#GUI end`
Next below here is the right side UI coding, there are multiple files for it. I just show files related with the UI only.
Consts.py
ENTRY_WIDTH = 50
FileReportTab.py
from tkinter import filedialog
from tkinter import messagebox
from tkinter import ttk
from tkinter import StringVar
import time
import os.path
import sys
from VTPackage import Consts
class FileReportTab:
def __init__(self, root, frame, vtClient):
self.root = root
self.frame = frame
self.vtClient = vtClient
self.mainVTURLframe = ttk.LabelFrame(frame, text=' File report')
self.mainVTURLframe.grid(column=0, row=1, padx=8, pady=4)
ttk.Label(self.mainVTURLframe, text="Progress:").grid(column=0, row=1, sticky='W') # <== right-align
self.progressBar = ttk.Progressbar(self.mainVTURLframe, orient='horizontal', length=300, mode='determinate')
self.progressBar.grid(column=1, row=1)
ttk.Label(self.mainVTURLframe, text="File path:").grid(column=0, row=2, sticky='W') # <== right-align
self.filePath = StringVar()
filePathEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.filePath, state='readonly')
filePathEntry.grid(column=1, row=2, sticky='W')
ttk.Label(self.mainVTURLframe, text="Status:").grid(column=0, row=3, sticky='W') # <== right-align
self.status = StringVar()
statusEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.status, state='readonly')
statusEntry.grid(column=1, row=3, sticky='W')
ttk.Label(self.mainVTURLframe, text="Positive Indications:").grid(column=0, row=4, sticky='W') # <== right-align
self.positiveIndications = StringVar()
positiveIndicationsEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.positiveIndications, state='readonly')
positiveIndicationsEntry.grid(column=1, row=4, sticky='W')
ttk.Label(self.mainVTURLframe, text="SHA1:").grid(column=0, row=5, sticky='W') # <== right-align
self.sha1 = StringVar()
sha1Entry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.sha1, state='readonly')
sha1Entry.grid(column=1, row=5, sticky='W')
ttk.Label(self.mainVTURLframe, text="SHA256:").grid(column=0, row=6, sticky='W') # <== right-align
self.sha256 = StringVar()
sha256Entry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=self.sha256, state='readonly')
sha256Entry.grid(column=1, row=6, sticky='W')
chooseFileButton = ttk.Button(self.mainVTURLframe, text="Choose File", width=40, command=self._scanFile).grid(column=1, row=0)
self.scanCheckingTimeInterval = 25000 # This is the amount of time we are going to wait before asking VT again if it already processed our scan request
for child in self.mainVTURLframe.winfo_children():
child.grid_configure(padx=4, pady=2)
def showResults(self, results):
try:
#self.file_Path = self.filePath
self.sha1.set(results["sha1"])
self.sha256.set(results["sha256"])
self.positiveIndications.set(results["positives"])
if results["positives"] == 0:
messagebox.showwarning("Analysis Info","File is Safe.\nOur Scanners found nothing Malicious")
elif results["positives"] <= 5:
messagebox.showwarning("Analysis Alert", "Given File may be Malicious")
elif results["positives"] >= 5:
messagebox.showwarning("Analysis Alert", f"Given File is Malicious.\nAdvice you remove the file from your System!")
res = messagebox.askyesno("Analysis Alert","The given file is highly Malicious.\nDo you want to Delete it permanently?")
if res == 1:
print("Attemting to delete file...")
time.sleep(1)
os.remove(self.filePath1)
#if os.PathLike(_scanFile.filePath):
# os.remove(self.filePath)
else:
print("This file cannot be deleted. Please do not use the fie. It's Malicious")
except Exception as e:
messagebox.showerror('Error', e)
def checkStatus(self):
try:
self.scanResult = self.vtClient.get_file_report(self.scanID)
print(self.scanResult)
if self.scanResult["response_code"] == -2: # By reading the next line, you can understand what is the meaning of the -2 response ode
self.status.set("Scanning...")
self.progressBar['value'] = self.progressBar['value'] + 5
self.root.update_idletasks()
self.mainVTURLframe.after(self.scanCheckingTimeInterval, self.checkStatus)
else:
self.hasScanFinished = True
self.showResults(self.scanResult)
self.status.set("Finished!")
self.progressBar['value'] = 100
except Exception as e:
if "To much API requests" in str(e):
pass
def _scanFile(self):
try:
self.progressBar['value'] = 0
self.filePath1 = filedialog.askopenfilename(initialdir="/", title="Select file for VT", filetypes=(("EXE files", "*.exe"), ("all files", "*.*")))
if (self.filePath): # Only if the user chose a file, we will want to continue the process
self.filePath.set(self.filePath1)
self.status.set("Sending file...")
self.progressBar['value'] = 10
self.root.update_idletasks()
self.scanID = self.vtClient.scan_file(self.filePath1)
self.hasScanFinished = False
if not self.hasScanFinished:
self.scanResult = self.vtClient.get_file_report(self.scanID)
print(self.scanResult)
self.checkStatus()
# We could have been using time.sleep() or time.wait(), but then our UI would get stuck.
# by using after, we are initiating a callback in which does not blocks our event loop
except Exception as e:
messagebox.showerror('Error', e)
URLreportTab.py
from tkinter import ttk
from tkinter import StringVar
from VTPackage import Consts
class URLreportTab:
def __init__(self, root, frame, vtClient):
self.root = root
self.frame = frame
self.mainVTURLframe = ttk.LabelFrame(frame, text=' URL report tab!')
# using the tkinter grid layout manager
self.mainVTURLframe.grid(column=0, row=0, padx=8, pady=4)
ttk.Label(self.mainVTURLframe, text="URL:").grid(column=0, row=0, sticky='W') # What does sticky does? Sticky sayes where to stick the label to : N,S,E,W
urlEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH)
urlEntry.grid(column=1, row=0, sticky='E')
ttk.Label(self.mainVTURLframe, text="Positive Indications:").grid(column=0, row=1, sticky='W') # <== right-align
Positive = StringVar()
PositiveEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=Positive, state='readonly')
PositiveEntry.grid(column=1, row=1, sticky='W')
ttk.Label(self.mainVTURLframe, text="Detections:").grid(column=0, row=2, sticky='W') # <== right-align
detections = StringVar()
detectionsEntry = ttk.Entry(self.mainVTURLframe, width=Consts.ENTRY_WIDTH, textvariable=detections, state='readonly')
detectionsEntry.grid(column=1, row=2, sticky='W')
self.notificationFrame = ttk.LabelFrame(self.frame, text=' Notifications', width=40)
# using the tkinter grid layout manager
self.notificationFrame.grid(column=0, row=1, padx=8, pady=10, sticky='W')
ttk.Label(self.notificationFrame, text="Errors:").grid(column=0, row=0, sticky='W') # <== increment row for each
Error = StringVar()
ErrorEntry = ttk.Entry(self.notificationFrame, width=Consts.ENTRY_WIDTH, textvariable=Error, state='readonly')
ErrorEntry.grid(column=1, row=0, sticky='W')
def _cleanErrorMessage(): # We could have been doing this without a function, but it is more neat that way
Error.set("")
def _getReport():
# the _ notation before a function means that this function is internal to the class only. As python cannot really prevent you from using it outside the class (as C# for example) the notation is being used to warn other developers not to call this function outside the class
try:
_cleanErrorMessage() # Starting with cleaning the error message bar
if not urlEntry.get():
print('Please enter a URL')
Error.set("Please enter a URL!")
return
urlToCheck = urlEntry.get()
response = vtClient.get_url_report(urlToCheck)
print(response)
Positive.set(response["positives"])
scans = response["scans"]
findings = set()
for key, value in scans.items():
if value["detected"]:
findings.add(value["result"])
detections.set(",".join([str(finding) for finding in findings]))
except Exception as e:
print(e)
Error.set(e)
checkURLinVTButton = ttk.Button(self.mainVTURLframe, text='Check Now!', command=_getReport).grid(column=2, row=0)
# Instead of setting padding for each UI element, we can just iterate through the children of the main UI object.
for child in self.mainVTURLframe.winfo_children():
child.grid_configure(padx=4, pady=2)
for child in self.notificationFrame.winfo_children():
child.grid_configure(padx=4, pady=2)
VTApp.py
import tkinter as tk
import configparser
from tkinter import Menu
from tkinter import ttk
from tkinter import messagebox
from VTPackage import URLreportTab
from VTPackage import FileReportTab
from VTPackage import VTClient
config = configparser.ConfigParser()
config.read('config.ini')
class VTApp:
def __init__(self):
# Loading the config file
self.config = configparser.ConfigParser()
self.config.read('config.ini')
self.virusTotalAPIkey = config['VirusTotal']['apiKey']
self.vtClient = VTClient.VTClient(self.virusTotalAPIkey)
self.root = tk.Tk()
self.root.title("Virus Total UI")
self.menuBar = Menu()
self.root.config(menu=self.menuBar)
self.fileMenu = Menu(self.menuBar, tearoff=0)
self.fileMenu.add_command(label="New")
self.fileMenu.add_separator()
self.menuBar.add_cascade(label="File", menu=self.fileMenu)
if not self.vtClient.is_API_key_valid():
messagebox.showerror('Error', "API key is not valid! Check your config file")
def _quit():
self.root.quit() # The app will exist when this function is called
self.root.destroy()
exit()
self.fileMenu.add_command(label="Exit", command=_quit) # command callback
self.tabControl = ttk.Notebook(self.root) # Create Tab Control
self.urlFrame = ttk.Frame(self.tabControl)
self.urlTab = URLreportTab.URLreportTab(self.root, self.urlFrame, self.vtClient)
self.tabControl.add(self.urlFrame, text='URL')
self.fileFrame = ttk.Frame(self.tabControl)
self.fileTab = FileReportTab.FileReportTab(self.tabControl, self.fileFrame, self.vtClient)
self.tabControl.add(self.fileFrame, text='File')
self.tabControl.pack(expand=1, fill="both") # Pack to make visible
def start(self):
self.root.mainloop()
Main.py
from VTPackage import VTApp
vtApp = VTApp.VTApp()
vtApp.start()
This is the original code, Sorry for the spacing error, I copy&paste from vsc and it seem like the got some spacing error after Class. So basically this is the original code and I try like import VTApp and code inside class Page2 like
vtApp = VTApp.VTApp()
vtApp.start()
and change some coding in the VTApp.py but it doesn't work.... Does anyone know how to make the script works? I been trying and trying for a week and still couldn't get the solution.
You cannot move a widget from one window to another in tkinter. You will have to recreate the tab in the other window.
I need to take a value from user and then pass this value into function to get a string with this values. My code in first file looks like below (of course it is simplified version):
import tkinter as tk
from tkinter import ttk
import myfunction # this is my module that has another function
class Interface(ttk.Frame):
def __init__(self, container):
super().__init__(container)
self.user_price_minimum = tk.StringVar()
minimum_price = ttk.Label(self, text="Minimum price is: ")
minimum_price.grid(row=0, column=0, padx=5, pady=5)
minimum_price_entry = ttk.Entry(self, width=15, textvariable = self.user_price_minimum)
minimum_price_entry.grid(row=0, column=1)
minimum_price_entry.focus()
#############
button = ttk.Button(self, text="Use price")
button.grid(column=0, rows=2, columnspan=2, padx=5, pady=5)
root = tk.Tk()
root.geometry("450x250")
root.title("Looking for a flat")
root.columnconfigure(0, weight=1)
frame = Interface(root)
frame.pack()
root.mainloop()
My another python file that calls myfunction.py should be able to take this minimum_price from user and add this into string. Code looks like below:
def minimum_price(self):
price_min = self.user_price_minimum.get()
price_min = int(price_min)
print(f'Minimum price is: {price_min}')
So I am not sure how I could use minimum_price values from user into this function.
The simplest is to do this:
button = ttk.Button(self, text="Use price", command=lambda: myfunction.minimum_price(self))
However you could also define it as a method in the class itself:
class Interface(ttk.Frame):
def __init__(self, container):
super().__init__(container)
self.user_price_minimum = tk.StringVar()
minimum_price = ttk.Label(self, text="Minimum price is: ")
minimum_price.grid(row=0, column=0, padx=5, pady=5)
minimum_price_entry = ttk.Entry(self, width=15, textvariable = self.user_price_minimum)
minimum_price_entry.grid(row=0, column=1)
minimum_price_entry.focus()
#############
button = ttk.Button(self, text="Use price", command=self.print_price)
button.grid(column=0, rows=2, columnspan=2, padx=5, pady=5)
def print_price(self):
price = self.user_price_minimum.get()
print(f'Minimum price: {price}')
My personal preference (when using another file in such a case like this one (tho I would probably prefer to define this as above)) would be if:
# in the other file
def minimum_price(value):
print(f'Minimum price: {value}')
# inside the class
button = ttk.Button(self, text="Use price", command=lambda: myfunction.minimum_price(self.user_price_minimum.get()))
Also in this case you don't necessarily need the StringVar, you could also simply get the value by using:
# assignment
self.minimum_price_entry = ttk.Entry(self, width=15)
# get value (probably in some function call, basically the same way as with the `StringVar` except less code)
self.minimum_price_entry.get()
relatively new to coding and currently I am playing with tkinter in python, I am using a text widget within a function and want to send the input from the text box to another function. My global variable says undefined at module level, so How could I make it defined at a module level if its within a function?
When I press the send email button I get this error message "NameError: name 'user_message_entry' is not defined"
Any suggestions? Many thanks!
minimum reproduction:
import tkinter as tk
root = tk.Tk()
root.geometry("500x500")
def send_email():
global user_message_entry
subject = ":)"
body = user_message_entry.get("1.0", "end")
message = f"subject: {subject}\n\n {body}"
print(message)
def feedback():
feedback_window = tk.Toplevel()
feedback_window.geometry("690x650")
message_frame = tk.Frame(feedback_window)
message_frame.grid(row=0, column=0, columnspan=3)
user_message_entry = tk.Text(message_frame, height=10, width=60)
user_message_entry.grid(row=0, column=0)
send_email_button = tk.Button(feedback_window, command=send_email,
height=20, width=20, bg="yellow", text="send email")
send_email_button.grid(row=1, column=0)
open_feedback_button = tk.Button(root, command=feedback, height=20, width=20, bg="yellow", text="open feedback window")
open_feedback_button.grid(row=1, column=0)
root.mainloop()
You can use Object orient methodology to make access sympler, another option also you can use globals() to make variable global
One way
globals()['user_message_entry'] = tk.Text(message_frame, height=10, width=60)
....
and from another function you can call
body = globals()['user_message_entry'].get("1.0", "end")
Second way
Object oriented programming is good for every type of problem solving, so you can use class as well
import tkinter as tk
class CBased:
def __init__(self, master, *args, **kwargs):
super(CBased, self).__init__(*args, *kwargs)
self.master = master
master.geometry("500x500")
self.open_feedback_button = tk.Button(master, command=self.feedback, height=20, width=20, bg="yellow", text="open feedback window")
self.open_feedback_button.grid(row=1, column=0)
def send_email(self):
subject = ":)"
body = self.user_message_entry.get("1.0", "end")
message = f"subject: {subject}\n\n {body}"
print(message)
def feedback(self):
self.feedback_window = tk.Toplevel()
self.feedback_window.geometry("690x650")
self.message_frame = tk.Frame(self.feedback_window)
self.message_frame.grid(row=0, column=0, columnspan=3)
self.user_message_entry = tk.Text(self.message_frame, height=10, width=60)
self.user_message_entry.grid(row=0, column=0)
self.send_email_button = tk.Button(self.feedback_window, command=send_email,
height=20, width=20, bg="yellow", text="send email")
self.send_email_button.grid(row=1, column=0)
def main():
root = Tk()
myobj = CBased(root)
root.mainloop()
if __name__ == "__main__":main()
In this way you can call every single item by self.xyz
I have the following Tkinter application which basically helps you to configure a new network just by inserting in the entry box a new value. This value entered by the user it is saved somewhere in a file using the template. This script runs well, but problem is that I am seeing the Tenant entry box upper than Network name entry box. The same is happening with their labels. Then, when we click on the Add network and getting another 2 entry box, are displayed very strange way.
How can I align the labels + entry boxes and how can I have them displayed each group of label+entry box one bellow the other?
Something like:
Tenant [entrybox] Network [entrybox]
Tenant [entrybox] Network [entrybox]
....................................
import Tkinter as tk
class SampleApp(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self._frame = None
self.networks = []
self.switch_frame(StartPage)
def switch_frame(self, frame_class):
"""Destroys current frame and replaces it with a new one."""
new_frame = frame_class(self)
if self._frame is not None:
self._frame.destroy()
self._frame = new_frame
self._frame.pack()
class StartPage(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
start_label = tk.Label(self, text="This is the start page")
network_button = tk.Button(self, text="Create the networks", command=lambda: master.switch_frame(Networks))
start_label.pack(side="top", fill="x", pady=10)
deployment_button.pack()
network_button.pack()
subnet_button.pack()
neutronports_button.pack()
script_button.pack()
class Networks(tk.Frame):
def __init__(self, master):
tk.Frame.__init__(self, master)
self.entries=[]
self.create_widgets(master)
def create_widgets(self, master):
label = tk.Label(self, text="Insert the name of the networks")
start_button = tk.Button(self, text="Return to start page", command=lambda: master.switch_frame(StartPage))
new_network_button = tk.Button(self, text="Add network", command=self.add_network)
new_network_button.bind("<Return>", self.add_network)
new_network_button.grid(row=len(self.master.networks), column=3, padx=4, pady=6, sticky="W")
next_button=tk.Button(self, text="Submit", command=self.networks)
next_button.grid(row=1500, column=5,padx=4, pady=6, sticky="W")
label.pack(side="top", fill="x", pady=10)
start_button.pack()
new_network_button.pack()
next_button.pack()
for index, network in enumerate(self.master.networks):
self.render_network_field(network, index)
def add_network(self):
requirements={'variable': tk.StringVar(self.master), 'cloudvariable': tk.StringVar(self.master)}
if requirements:
self.master.networks.append(requirements)
self.master.switch_frame(Networks)
else:
tkMessageBox.showerror("tk", "No networks defined!")
self.master.switch_frame(Networks)
def render_network_field(self, network, index):
labelText=tk.StringVar()
labelText.set("Tenant name")
labelDir=tk.Label(self,textvariable=labelText, height=4)
labelDir.pack(side="top")
nw_entry_field = tk.Entry(self, textvariable=network['variable'])
nw_entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
nw_entry_field.pack(side="right")
labelText=tk.StringVar()
labelText.set("Network name")
labelDir=tk.Label(self,textvariable=labelText, height=4)
labelDir.pack(side="top")
cloud_entry_field = tk.Entry(self, textvariable=network['cloudvariable'])
cloud_entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
cloud_entry_field.pack(side="right")
self.entries.append((network['cloudvariable'],network['variable']))
def networks(self):
with open("/home/dante/networks.yml", "w") as f:
f.write("--- #" + "\n")
for ent, cloudent in self.entries:
network_value=ent.get()
cloud_value=cloudent.get()
if network_value:
if cloud_value:
f.write("- { cloud: "+cloud_value+", network: "+network_value+ " }"+ "\n")
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
Following is a simple code that I just made to solve your problem. You just have to put the function register() in your class, that is executed when you press the button register (put it in the same class).
import tkinter as tk
from tkinter import *
def register():
username = x1.get()
password = y1.get()
if username!="" and password=="":
file = open("accountfile.txt","a")
file.write(username)
file.write(" ")
file.write(password)
file.write("\n")
file.close()
root=Tk()
# String variables
x1=StringVar()
y1=StringVar()
Us=Entry(root,textvariable=x1)
Us.grid()
Ps=Entry(root, textvariable=y1)
Ps.grid()
Reg=Button(root,text="Register",command=lambda:register())
Reg.grid()
root.mainloop()
Edit:
To solve your error, make s a global variable. This will define s for all blocks of code in the file. Also, you can set a new value to it and then, use the new value, anywhere else
global s
s=""
def networks(self):
with open("/home/dante/networks.yml", "w") as f:
f.write("--- #" + "\n")
f.write("networks:" + "\n")
for ent in s:
if ent:
f.write("- { cloud: cloud1, network: "+str(ent)+ " }"+ "\n")
def render_network_field(self, network, index):
entry_field = tk.Entry(self, textvariable=network['variable'])
entry_field.grid(row=index, column=0, columnspan=2, padx=4, pady=6, sticky="NEWS")
entry_field.pack()
global s
s=entry_field.get()
Hope this helps
I have only been programming 3 months so any advice on improvement to my code is appreciated even if it inst related to my specific question.
Its a simple small project with tkinter. Two fields to enter your first and last name then you hit the swap button and it will swap what ever you put in the name fields.
Problem is I dont want to use globals and I cant seem to figure it out I know its probably something easy and I did spend time trying to figure it out.
If you have any improvements to the code let me know.
from tkinter import *
### I dont Want Globals but cant figure out another method for doing this
### Hope some one can help me with this part
evar = ""
evar1 = ""
def mainWindow():
root = Tk()
root.title("Swap Names")
root.geometry("400x150+100+250")
return root
def createVar():
global evar
global evar1
evar = StringVar()
evar1 = StringVar()
def firstNameFrame(root):
frame1 = Frame(root)
frame1.pack(side=TOP, padx=2, pady=2)
label = Label(frame1, text="First Name:")
label.pack(side=LEFT, padx=2, pady=2)
entry = Entry(frame1, textvariable = evar)
entry.pack(side=LEFT, pady = 2)
def lastNameFrame(root):
frame2 = Frame(root)
frame2.pack(side=TOP, padx=2, pady=2)
label = Label(frame2, text="Last Name:")
label.pack(side=LEFT, padx=1, pady=1)
entry = Entry(frame2, textvariable = evar1)
entry.pack(side=LEFT, pady = 5)
def swapFrame(root):
frame3 = Frame(root)
frame3.pack(side=TOP, padx=10, pady = 10)
swapButton = Button(frame3, text="Swap",command = swap)
swapButton.pack(side=LEFT, padx =5, pady=5)
### I would like to some how use swap with out using a global
def swap():
b=evar.get()
evar.set(evar1.get())
evar1.set(b)
def main():
root = mainWindow()
createVar()
firstNameFrame(root)
lastNameFrame(root)
swapFrame(root)
root.mainloop()
main()
One of the solutions can be wrapping all the code related to the initialization and working with Tk in a separate class, so instead of global variables, we will use the class instance variables:
from tkinter import *
class Gui(object):
def __init__(self):
self.root = Gui._init_main_window()
self.first_name_var = StringVar()
self.last_name_var = StringVar()
self._init_first_name_frame()
self._init_last_name_frame()
self._init_swap_frame()
#staticmethod
def _init_main_window():
root = Tk()
root.title("Swap Names")
root.geometry("400x150+100+250")
return root
def _init_first_name_frame(self):
frame1 = Frame(self.root)
frame1.pack(side=TOP, padx=2, pady=2)
label = Label(frame1, text="First Name:")
label.pack(side=LEFT, padx=2, pady=2)
entry = Entry(frame1, textvariable=self.first_name_var)
entry.pack(side=LEFT, pady=2)
def _init_last_name_frame(self):
frame2 = Frame(self.root)
frame2.pack(side=TOP, padx=2, pady=2)
label = Label(frame2, text="Last Name:")
label.pack(side=LEFT, padx=1, pady=1)
entry = Entry(frame2, textvariable=self.last_name_var)
entry.pack(side=LEFT, pady=5)
def _init_swap_frame(self):
frame3 = Frame(self.root)
frame3.pack(side=TOP, padx=10, pady=10)
swap_button = Button(frame3, text="Swap", command=self._swap)
swap_button.pack(side=LEFT, padx=5, pady=5)
def _swap(self):
tmp = self.first_name_var.get()
self.first_name_var.set(self.last_name_var.get())
self.last_name_var.set(tmp)
def mainloop(self):
return self.root.mainloop()
def main():
gui = Gui()
gui.mainloop()
if __name__ == '__main__':
main()
A small comment to the code above: adding a prefix __ to variables or methods allows you to hide access to them directly by name outside the class using the name mangling.
UPD: According to #Coal comment, changed the double underscore prefixes to single underscore, as there is no need to use a name mangling.
This is assuming that when you say you don't want to use global, that you also mean that you don't want to use self:
from tkinter import Tk, Button, Entry
def swap(fn, ln):
# Get the contents of the two fields.
first = fn.get()
last = ln.get()
# Clear the contents of both fields.
first_name.delete(0, 'end')
last_name.delete(0, 'end')
# Set each field to the previous content of the other field.
first_name.insert(0, last)
last_name.insert(0, first)
root = Tk()
first_name = Entry(root)
last_name = Entry(root)
first_name.insert(0, "Enter first name")
last_name.insert(0, "Enter last name")
first_name.pack()
last_name.pack()
swap_button = Button(root, text="SWAP", command=lambda:swap(first_name, last_name))
swap_button.pack()
root.mainloop()