Python Tkinter网格设置



我的第一个编码项目,我正在尝试创建一个应用程序,用作旧笔记本电脑上的仪表板。

天气应用程序概念

我可以像图片中那样使用tkinters网格来创建方框吗?

我已经跌跌撞撞了两天,我根本无法拿出一个好的结果,也没有创造出一个好成绩。

这是我的代码:

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()

向特金特贵寻求建议。我在想,你可以创建盒子,并设置所有的";小部件";或它们内部的数据。

对于e.x,创建一个框并将其放在左侧,并在其中包含天气状态和信息。用于选择城市的按钮的NW框。方框N显示大文本,它显示的是哪个城市的信息。

这在特金特可能吗?

如果我留下的信息不足,或者这是一条太松散的线索,无法得到帮助,请写信告诉我,我是这方面的新手,所以我感谢所有的帮助。

谨致问候!

我会使用Frames来组织视图。您不应该使用随机较大的数字来尝试将内容隔开(空的行和列在填充内容之前保持为零(,而应该查看grid.row(or column)configureweight选项以及grid本身的row(or column)span选项。

为了实现你的观点,你可能想从这样的东西开始:

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()

编辑:

在使用类时,总是调用__init__函数,请参阅。你可以使用彼此内部的其他函数,但你不能只是把它扔在那里,然后期望它在不被调用的情况下运行,你可能想看看内部函数。

但在你的情况下,我不会这么做。

我会创建两个新的其他类(1个用于顶部框架,1个用于底部框架(,并从tk.Frame类继承,原因有两个:

  1. 可读性,因为一切都在它所属的地方,并且很好地组合在一起
  2. 可重用性,因为所有底部框架的内容都是相同的(小部件方面(,所以您只需传递值即可更改:
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()

此外,请注意,当谈到在同一行中使用.grid(row=0, column=0)时,thezzard对我的草率所说的话,因为一旦你想更改变量的任何内容,你就会遇到错误!

感谢Newb和其他人的不同回答。

我使用了Newb的代码,并做了一些更改,比如将其做成12格,并更改帧应该在哪里的顺序。

我还试图实现";天气;原始代码中的代码,这就是我被卡住的地方。

你能把一个函数放在另一个函数里吗?

我仍然不明白init的作用,但我可以从侧面学习。

这是更新后的代码:

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()

你已经帮了我很多,但如果你想帮助我如何实现这一点,请放心。

谢谢,祝你今天过得愉快!

编辑:

嗨!很抱歉撞到了一个旧线程,我仍在努力使这个应用程序正常工作!

当我尝试运行以下代码时,我会得到NameError:"名称"city_listbox"未定义代码"在第172行

任何人都有任何精力和线索,我可以做些什么来在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()

谨致问候,Joggster!

最新更新