[英]Python Tkinter grid set up
My first coding project, and I am trying to create an app to use as a dashboard on an old laptop.我的第一个编码项目,我正在尝试创建一个应用程序,用作旧笔记本电脑上的仪表板。
Can I use tkinters grid to create boxes like in the picture?我可以使用 tkinter 网格来创建图片中的框吗?
I have stumbled for two days and I cannot come up with a good result at all nor have I managed to create a good box yet.我已经跌跌撞撞了两天,我根本无法想出一个好的结果,也没有设法创造出一个好的盒子。
Here is my code:这是我的代码:
import requests
from tkinter import *
from PIL import ImageTk, Image
def weather():
city=city_listbox.get()
url="https://api.openweathermap.org/data/2.5/weather?q={}&appid=*myappid*&units=metric".format(city)
res=requests.get(url)
output=res.json()
weather_status=output['weather'][0]['description']
temperature=output['main']['temp']
feelslike=output['main']['feels_like']
humidity=output['main']['humidity']
wind_speed=output['wind']['speed']
weather_status_label.configure(text="Weather status : "+ weather_status)
if weather_status=="few clouds":
partial_cloud_label=Label(image=partial_cloud)
partial_cloud_label.grid(row=3, column=4)
temperature_label.configure(text="Temperature : "+ str(temperature) +"°C")
feelslike_label.configure(text="Feels like : "+ str(feelslike) +"°C")
humidity_label.configure(text="Humidity : "+ str(humidity) +"%")
wind_speed_label.configure(text="Wind speed : "+ str(wind_speed) +"m/s")
window=Tk()
window.geometry("1920x1080")
window.iconbitmap('localfile')
window.title('Show dis weather')
partial_cloud=ImageTk.PhotoImage(Image.open("local file"))
day_clear=ImageTk.PhotoImage(Image.open("localfile"))
cloudy=ImageTk.PhotoImage(Image.open("localfile"))
city_name_list=["City1", "City2"]
city_listbox=StringVar(window)
city_listbox.set("select the city")
option=OptionMenu(window,city_listbox,*city_name_list)
option.grid(row=2,column=6,padx=150,pady=10)
b1=Button(window,text="Select",width=15,command=weather)
b1.grid(row=5,column=6,padx=150)
weather_status_label=Label(window, font=("didot",15,"bold"))
weather_status_label.grid(row=10,column=6)
temperature_label=Label(window,font=("didot",15,"bold"))
temperature_label.grid(row=16,column=6)
feelslike_label=Label(window,font=("didot",15,"bold"))
feelslike_label.grid(row=22,column=6)
humidity_label=Label(window,font=("didot",15,"bold"))
humidity_label.grid(row=28,column=6)
wind_speed_label=Label(window,font=("didot",15,"bold"))
wind_speed_label.grid(row=34,column=6)
window.mainloop()
Seeking advice towards Tkinter gui.寻求对 Tkinter gui 的建议。 I was thinking that you could possibly create boxes and set all the "widgets" or data inside them.我在想,您可以创建框并在其中设置所有“小部件”或数据。
For ex, creating a box and put it to the left and have the weather status and information inside there.例如,创建一个框并将其放在左侧并在其中包含天气状态和信息。 A box NW for the buttons to choose city.用于选择城市的按钮的 NW 框。 Box N to show big text for which city it is showing information for.框 N 显示它正在显示信息的城市的大文本。
Is this possible in Tkinter?这在 Tkinter 中可能吗?
If I have left insufficient information or if this is a too loose thread to being helped through, please write and tell me about it, I am very new in this, so I appreciate all help.如果我没有留下足够的信息,或者如果这是一个太松散的线索而无法获得帮助,请写信告诉我,我对此很陌生,所以我感谢所有帮助。
With Regards!带着敬意!
I would use Frames in order to organize the view.我会使用框架来组织视图。 And instead of using random bigger numbers to try spacing things out(empty rows and columns stay at size zero until filled with content), you should take a look into the weight
option of grid.row(or column)configure
as well as the row(or column)span
option of grid
itself.而不是使用随机更大的数字来尝试将事物grid.row(or column)configure
空行和列保持大小为零,直到填充内容),您应该查看grid.row(or column)configure
的weight
选项以及row(or column)span
grid
本身的row(or column)span
选项。
in order to achieve your view you might wanna start with something like this:为了实现你的观点,你可能想从这样的事情开始:
import tkinter as tk
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#Window config
tk.Tk.wm_title(self, "WeatherApp")
self.geometry("1920x1080")
#Main Layout
self.mainframe = tk.Frame(self)
self.mainframe.pack(fill="both", expand = True)
self.mainframe.grid_rowconfigure(0, weight=1)
self.mainframe.grid_rowconfigure(1, weight=1)
self.mainframe.grid_columnconfigure(0, weight=1)
self.mainframe.grid_columnconfigure(1, weight=1)
self.mainframe.grid_columnconfigure(2, weight=1)
self.mainframe.grid_columnconfigure(3, weight=1)
#Top Container
self.top = tk.Frame(self.mainframe)
#placing in the main frame
self.top.grid(row = 0, column = 0, columnspan = 4)
#configure layout for top view
self.top.grid_rowconfigure(0, weight=1)
self.top.grid_columnconfigure(0, weight=1)
#content of top view
self.toplabel = tk.Label(self.top, text = "City: ")
self.toplabel.grid(row = 0, column = 0)
#day1
self.day1 = tk.Frame(self.mainframe)
#placing in the main frame
self.day1.grid(row = 1, column = 0)
#configure layout for top view
self.day1.grid_rowconfigure(0, weight=1)
self.day1.grid_columnconfigure(0, weight=1)
#content of day1 frame
self.label1 = tk.Label(self.day1, text="saturday")
self.label1.grid(row = 0, column = 0)
#day2
self.day2 = tk.Frame(self.mainframe)
#placing in the main frame
self.day2.grid(row = 1, column = 1)
#you don't have to configure if all cells should have equal size
#content of day1 frame
self.label2 = tk.Label(self.day2, text="sunday")
self.label2.grid(row = 0, column = 0)
#day3
self.day3 = tk.Frame(self.mainframe)
#placing in the main frame
self.day3.grid(row = 1, column = 2)
#content of day1 frame
self.label3 = tk.Label(self.day3, text="monday")
self.label3.grid(row = 0, column = 0)
#day4
self.day4 = tk.Frame(self.mainframe)
#placing in the main frame
self.day4.grid(row = 1, column = 3)
#content of day1 frame
self.label4 = tk.Label(self.day4, text="tuesday")
self.label4.grid(row = 0, column = 0)
app = Application()
app.mainloop()
EDIT:编辑:
The __init__
function is always getting called when a class is being used, see . __init__
函数总是在使用类时被调用,请参阅。 You can use other functions from within each other, but you can't just toss it in there and expect it to run without beeing called, you might wanna take a look at inner Functions .您可以在彼此内部使用其他函数,但您不能将它扔在那里并期望它在没有被调用的情况下运行,您可能想看看内部 Functions 。
But that isn't what I would do in your case.但这不是我在你的情况下会做的。
I would create 2 new other classes (1 for top frame, 1 for bottom frame) and inhereting from the tk.Frame
class for 2 reasons:我会创建 2 个新的其他类(1 个用于顶部框架,1 个用于底部框架)并从tk.Frame
类tk.Frame
,原因有两个:
import tkinter as tk
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#Window config
tk.Tk.wm_title(self, "WeatherApp")
self.geometry("1920x1080")
#Main Layout
self.mainframe = tk.Frame(self)
self.mainframe.pack(fill="both", expand = True)
self.mainframe.grid_rowconfigure(0, weight=1)
self.mainframe.grid_rowconfigure(1, weight=1)
self.mainframe.grid_columnconfigure(0, weight=1)
self.mainframe.grid_columnconfigure(1, weight=1)
self.mainframe.grid_columnconfigure(2, weight=1)
self.mainframe.grid_columnconfigure(3, weight=1)
#Top Container
#note the changed declaration, since we're now calling
#our own Frame class
self.top = TopFrame(self.mainframe)
#placing in the main frame
self.top.grid(row = 0, column = 0, columnspan = 4)
#day1
# note the passthrough of the day argument
self.day1 = DayFrame(self.mainframe, "saturday")
#placing in the main frame
self.day1.grid(row = 1, column = 0)
#day2
self.day2 = DayFrame(self.mainframe, "sunday")
#placing in the main frame
self.day2.grid(row = 1, column = 1)
#day3
self.day3 = DayFrame(self.mainframe, "monday")
#placing in the main frame
self.day3.grid(row = 1, column = 2)
#day4
self.day4 = DayFrame(self.mainframe, "tuesday")
#placing in the main frame
self.day4.grid(row = 1, column = 3)
class TopFrame(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
#add code for your widgets in top frame here
label = tk.Label(self, text="Top Frame")
label.grid(row = 0, column = 0)
class DayFrame(tk.Frame):
def __init__(self, parent, day):
tk.Frame.__init__(self, parent)
# add code for bottom frame widgets here
# pass nessecary variables through to reuse the code
self.day = day
self.daylabel = tk.Label(self, text = day)
self.daylabel.grid(row = 0, column = 0)
app = Application()
app.mainloop()
Also please note what thelizzard said about my sloppiness when it comes to using .grid(row=0, column=0)
in the same row, because you will run into errors with this as soon as you want to change anything about the variable!还请注意 thelizzard 在同一行中使用.grid(row=0, column=0)
时对我的草率所说的话,因为只要您想更改有关变量的任何内容,就会遇到错误!
Thank you Newb, and you others, for different answers.谢谢 Newb 和其他人的不同答案。
I have used Newb's code and made some changes, like making it a 12 grid big and changing the order of where the frames should be.我使用了 Newb 的代码并进行了一些更改,例如将其设置为 12 格大并更改帧的位置顺序。
I have also tried to implement the "weather" code from the original code, and there is where I got stuck.我还尝试从原始代码中实现“天气”代码,但我遇到了困难。
Can you put a function inside another function?你能把一个函数放在另一个函数中吗?
I still cannot understand what init is for, but that I can learn on the side.我仍然无法理解 init 的用途,但我可以一边学习。
Here is the updated code:这是更新后的代码:
import tkinter as tk
#from tkinter import *
from PIL import ImageTk, Image
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
#Window config
tk.Tk.wm_title(self, "WeatherApp")
self.geometry("1920x1080")
self.iconbitmap('localfile')
#This part I have added
self.partial_cloud=ImageTk.PhotoImage(Image.open("localfile"))
self.day_clear=ImageTk.PhotoImage(Image.open("localfile"))
self.cloudy=ImageTk.PhotoImage(Image.open("localfile"))
#This part I have added
def weather():
self.city=city_listbox.get()
self.url="https://api.openweathermap.org/data/2.5/weather?q={}&appid=*myappid*&units=metric".format(city)
self.res=requests.get(url)
self.output=res.json()
self.weather_status=output['weather'][0]['description']
self.temperature=output['main']['temp']
self.feelslike=output['main']['feels_like']
self.humidity=output['main']['humidity']
self.wind_speed=output['wind']['speed']
self.weather_status_label.configure(text="Weather status : "+ weather_status)
if weather_status=="few clouds":
partial_cloud_label=Label(image=partial_cloud)
partial_cloud_label.grid(row=3, column=4)
temperature_label.configure(text="Temperature : "+ str(temperature) +"°C")
feelslike_label.configure(text="Feels like : "+ str(feelslike) +"°C")
humidity_label.configure(text="Humidity : "+ str(humidity) +"%")
wind_speed_label.configure(text="Wind speed : "+ str(wind_speed) +"m/s")
#Main Layout
self.mainframe = tk.Frame(self)
self.mainframe.pack(fill="both", expand = True)
self.mainframe.grid_rowconfigure(0, weight=1)
self.mainframe.grid_rowconfigure(1, weight=1)
self.mainframe.grid_rowconfigure(2, weight=1)
self.mainframe.grid_columnconfigure(0, weight=1)
self.mainframe.grid_columnconfigure(1, weight=1)
self.mainframe.grid_columnconfigure(2, weight=1)
self.mainframe.grid_columnconfigure(3, weight=1)
#Top Left Container
self.tl = tk.Frame(self.mainframe)
#placing in the main frame
self.tl.grid(row = 0, column = 0)
#configure layout for top view
self.tl.grid_rowconfigure(0, weight=1)
self.tl.grid_columnconfigure(0, weight=1)
#This part I have added
#content of top view
self.city_name_list=["city1", "city2"]
self.city_listbox=StringVar(self.tl)
self.city_listbox.set("select the city")
self.option=OptionMenu(self.tl,city_listbox,*city_name_list)
self.option.grid(row=0,column=0,padx=150,pady=10)
self.b1=Button(self.tl, text="Select",width=15,command=weather)
self.b1.grid(row=0,column=0,padx=150)
#self.tllabel = tk.Label(self.tl, text = "Button ", font=("Sentinel", 20, "bold"))
#self.tllabel.grid(row = 0, column = 0)
#Top Middle Container (tm)
self.tm = tk.Frame(self.mainframe)
#placing in the main frame
self.tm.grid(row = 0, column = 1) #Leaving comment for my self columnspan = 4
#configure layout for top view
self.tm.grid_rowconfigure(0, weight=1)
self.tm.grid_columnconfigure(0, weight=1)
#content of top view
self.tmlabel = tk.Label(self.tm, text = "City: ", font=("Sentinel", 36, "bold"))
self.tmlabel.grid(row = 0, column = 0)
#Left Container
self.left = tk.Frame(self.mainframe)
#placing in the main frame
self.left.grid(row = 1, column = 0)
#configure layout for top view
self.left.grid_rowconfigure(0, weight=1)
self.left.grid_columnconfigure(0, weight=1)
#content of top view
self.leftlabel = tk.Label(self.left, text = "Weather ", font=("Sentinel", 20, "bold"))
self.leftlabel.grid(row = 0, column = 0)
#day1
self.day1 = tk.Frame(self.mainframe) # Tried to make a border, leaving comment for my self width=3, height=100, highlightbackground="black", highlightthickness=1) #bd=100)#relief=tk.RIDGE)
#placing in the main frame
self.day1.grid(row = 2, column = 0)
#configure layout for top view
self.day1.grid_rowconfigure(0, weight=1)
self.day1.grid_columnconfigure(0, weight=1)
#content of day1 frame
self.label1 = tk.Label(self.day1, text="Saturday", font=("Sentinel", 26, "bold")).grid(row = 0, column = 0)
#day2
self.day2 = tk.Frame(self.mainframe)
#placing in the main frame
self.day2.grid(row = 2, column = 1)
#you don't have to configure if all cells should have equal size
#content of day1 frame
self.label2 = tk.Label(self.day2, text="Sunday", font=("Sentinel", 26, "bold")).grid(row = 0, column = 0)
#day3
self.day3 = tk.Frame(self.mainframe)
#placing in the main frame
self.day3.grid(row = 2, column = 2)
#content of day1 frame
self.label3 = tk.Label(self.day3, text="Monday", font=("Sentinel", 26, "bold")).grid(row = 0, column = 0)
#day4
self.day4 = tk.Frame(self.mainframe)
#placing in the main frame
self.day4.grid(row = 2, column = 3)
#content of day1 frame
self.label4 = tk.Label(self.day4, text="Tuesday", font=("Sentinel", 26, "bold")).grid(row = 0, column = 0)
app = Application()
app.mainloop()
You have already helped me a lot, but if you feel to help me how to implement this, feel free to do it.你已经帮了我很多,但如果你想帮助我如何实现这一点,请随时去做。
Thanks and have a great day!谢谢,祝你有美好的一天!
EDIT:编辑:
Hi there!你好呀! Sorry for bumping an old thread, I am still working to make this application working!很抱歉碰到旧线程,我仍在努力使此应用程序正常工作!
When I am trying to run the following code, I get the NameError: "name 'city_listbox' is not defined code" at line 172当我尝试运行以下代码时,我在第 172 行收到 NameError: "name 'city_listbox' is not defined code"
Anyone has any energy and clue what I can do to implement the Weather code inside the grid code supplied from Newb?任何人都有任何能量和线索我可以做些什么来实现 Newb 提供的网格代码中的天气代码?
import requests
import tkinter as tk
#from tkinter import *
from PIL import ImageTk, Image
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
def weather():
def __init__(self, TopLFrame):
city=city_listbox.get()
url="https://api.openweathermap.org/data/2.5/weather?q={}&appid=ID&units=metric".format(city)
res=requests.get(url)
output=res.json()
weather_status=output['weather'][0]['description']
temperature=output['main']['temp']
feelslike=output['main']['feels_like']
humidity=output['main']['humidity']
wind_speed=output['wind']['speed']
weather_status_label.configure(text="Weather status : "+ weather_status)
if weather_status=="few clouds":
partial_cloud_label=tk.Label(image=partial_cloud)
partial_cloud_label.grid(row=3, column=4)
temperature_label.configure(text="Temperature : "+ str(temperature) +"°C")
feelslike_label.configure(text="Feels like : "+ str(feelslike) +"°C")
humidity_label.configure(text="Humidity : "+ str(humidity) +"%")
wind_speed_label.configure(text="Wind speed : "+ str(wind_speed) +"m/s")
#Window config
tk.Tk.wm_title(self, "WeatherApp")
self.geometry("1920x1080")
#self.iconbitmap('linktopicture')
#self.partial_cloud=ImageTk.PhotoImage(Image.open("linktopicture"))
#self.day_clear=ImageTk.PhotoImage(Image.open("linktopicture"))
#self.cloudy=ImageTk.PhotoImage(Image.open("linktopicture"))
#Main Layout
self.mainframe = tk.Frame(self)
self.mainframe.pack(fill="both", expand = True)
self.mainframe.grid_rowconfigure(0, weight=1)
self.mainframe.grid_rowconfigure(1, weight=1)
self.mainframe.grid_rowconfigure(2, weight=1)
self.mainframe.grid_columnconfigure(0, weight=1)
self.mainframe.grid_columnconfigure(1, weight=1)
self.mainframe.grid_columnconfigure(2, weight=1)
self.mainframe.grid_columnconfigure(3, weight=1)
#Top Left Container
self.tl = TopLFrame(self.mainframe, weather)
self.tl.grid(row = 0, column = 0)
#self.tl.grid_rowconfigure(0, weight=1)
#self.tl.grid_columnconfigure(0, weight=1)
#Top Middle Container (tm)
self.tm = TopMFrame(self.mainframe)
self.tm.grid(row = 0, column = 1)
#self.tm.grid_rowconfigure(0, weight=1)
#self.tm.grid_columnconfigure(0, weight=1)
#Left Container
self.left = MidFrame(self.mainframe)
self.left.grid(row = 1, column = 0)
#self.left.grid_rowconfigure(0, weight=1)
#self.left.grid_columnconfigure(0, weight=1)
#day1
self.day1 = BottomFrame(self.mainframe, "Monday")
self.day1.grid(row = 2, column = 0)
#self.day1.grid_rowconfigure(0, weight=1)
#self.day1.grid_columnconfigure(0, weight=1)
#day2
self.day2 = BottomFrame(self.mainframe, "saturday")
#placing in the main frame
self.day2.grid(row = 2, column = 1)
#day3
self.day3 = BottomFrame(self.mainframe, "test")
self.day3.grid(row = 2, column = 2)
#day4
self.day4 = BottomFrame(self.mainframe, "test2")
self.day4.grid(row = 2, column = 3)
class TopMFrame(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
#add code for your widgets in top frame here
self.label = tk.Label(self, text="Top Mid Frame")
self.label.grid(row = 0, column = 0)
class TopLFrame(tk.Frame):
def __init__(self, parent, Application):
tk.Frame.__init__(self, parent)
self.city_name_list=["City1", "City2"]
self.city_listbox=tk.StringVar(self)
self.city_listbox.set("select the city")
self.option=tk.OptionMenu(self, city_listbox, *city_name_list)
self.option.grid(row=0,column=0,padx=150,pady=10)
self.b1=tk.Button(self, text="Select",width=15,command=weather)
self.b1.grid(row=0,column=0,padx=150)
class MidLFrame(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.label = tk.Label(self, text="Left Frame")
self.label.grid(row = 0, column = 0)
self.weather_status_label=tk.Label(self, font=("didot",15,"bold"))
self.weather_status_label.grid(row=10,column=6)
self.temperature_label=tk.Label(self,font=("didot",15,"bold"))
self.temperature_label.grid(row=16,column=6)
self.feelslike_label=tk.Label(self,font=("didot",15,"bold"))
self.feelslike_label.grid(row=22,column=6)
self.humidity_label=tk.Label(self,font=("didot",15,"bold"))
self.humidity_label.grid(row=28,column=6)
self.wind_speed_label=tk.Label(self,font=("didot",15,"bold"))
self.wind_speed_label.grid(row=34,column=6)
class BottomFrame(tk.Frame):
def __init__(self, parent, day):
tk.Frame.__init__(self, parent)
# add code for bottom frame widgets here
# pass nessecary variables through to reuse the code
self.day = day
self.label1 = tk.Label(self, text = day, font=("Sentinel", 26, "bold"))
self.label1.grid(row = 0, column = 0)
app = Application()
app.mainloop()
With Regards, Joggster!问候,乔格斯特!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.