所以,我試圖創建一個元素周期表,它幾乎是從外部有效地完成的。但是,我不明白是否有任何方法可以以相同的方式在單個按鈕中填充顏色。任何人都可以幫我解決這個問題嗎?
下面是我的代碼:
from tkinter import *
period_1 = ['H','','','','','','','','','','','','','','','','','He']
period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
root = Tk()
root.attributes('-fullscreen', True)
root.config(bg='black')
Button(root, text='EXIT', bg='red', fg='white', command=root.destroy).place(x=0, y=0)
canvas_a = Canvas(root, bg='black', width=350, height=50)
canvas_a.place(relx=0.15, rely=0.3)
canvas1 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas1.pack()
canvas2 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas2.pack()
canvas3 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas3.pack()
canvas4 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas4.pack()
canvas5 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas5.pack()
canvas6 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas6.pack()
canvas7 = Canvas(canvas_a, bg='black', width=350, height=50)
canvas7.pack()
canvas_b = Canvas(root, bg='black', width=350, height=50)
canvas_b.place(relx=0.265, rely=0.8)
canvas8 = Canvas(canvas_b, bg='black', width=350, height=50)
canvas8.pack()
canvas9 = Canvas(canvas_b, bg='black', width=350, height=50)
canvas9.pack()
class Table:
def __init__(self):
for i in range(0,18):
Button(canvas1, text=period_1[i], width=6, height=2).pack(side=LEFT)
Button(canvas2, text=period_2[i], width=6, height=2).pack(side=LEFT)
Button(canvas3, text=period_3[i], width=6, height=2).pack(side=LEFT)
Button(canvas4, text=period_4[i], width=6, height=2).pack(side=LEFT)
Button(canvas5, text=period_5[i], width=6, height=2).pack(side=LEFT)
Button(canvas6, text=period_6[i], width=6, height=2).pack(side=LEFT)
Button(canvas7, text=period_7[i], width=6, height=2).pack(side=LEFT)
for i in range(0,15):
Button(canvas8, text=period_6a[i], width=6, height=2).pack(side=LEFT)
Button(canvas9, text=period_7a[i], width=6, height=2).pack(side=LEFT)
table1 = Table()
root.mainloop()
進一步說明:如果有人能告訴我如何為單個按鈕著色(如綠色為鹵素,藍色為金屬,紅色為氫)以及為每個按鈕命令創建頂層,我會很感激他/她。
uj5u.com熱心網友回復:
我用一些更好的方法重寫了你的代碼來創建表格。我的想法是挑出屬于某個型別范圍的按鈕,然后遍歷這些按鈕并將其顏色更改為這些型別。
from tkinter import *
period_1 = ['H' ,'','','','','','','','','','','','','','','','','He']
period_2 = ['Li','Be','','','','','','','','','','','B','C','N','O','F','Ne']
period_3 = ['Na','Mg','','','','','','','','','','','Al','Si','P','S','Cl','Ar']
period_4 = """K Ca Sc Ti V Cr Mn Fe Co Ni Cu Zn Ga Ge As Se Br Kr""".split(" ")
period_5 = """Rb Sr Y Zr Nb Mo Tc Ru Rh Pd Ag Cd In Sn Sb Te I Xe""".split(" ")
period_6 = """Cs Ba * Hf Ta W Re Os Ir Pt Au Hg Tl Pb Bi Po At Rn""".split(" ")
period_7 = """Fr Ra ** Rf D Sg Bh Hs Mt Ds Rg Cn Nh Fl Mc Lv Ts Og""".split(" ")
period_6a = """La Ce Pr Nd Pm Sm Eu Gd Tb Dy Ho Er Tm Yb Lu""".split(" ")
period_7a = """Ac Th Pa U Np Pu Am Cm Bk Cf Es Fm Md No Lr""".split(" ")
# Making a list of main elements and secondary elements
main = period_1 period_2 period_3 period_4 period_5 period_6 period_7
sec = period_6a period_7a
# Colors for each group
non_m_col = '#feab90'
alk_m_col = '#ffe0b2'
alk_ea_col = '#fecc81'
trans_m_col = '#d2c4e8'
halogen_col = '#a4d7a7'
metals_col = '#feab90'
noble_g_col = '#fefffe'
act_col = '#b2e5fd'
rare_m_col = '#e7ee9a'
root = Tk()
# Frame for the entire table
period_tab = Frame(root)
period_tab.pack()
# Frame for the main elements only
main_elem = Frame(period_tab)
main_elem.pack()
# Frame for the secondary elements only
sec_elem = Frame(period_tab)
sec_elem.pack(pady=10)
# Creating a 7x18 table of buttons and appending it to a 2D python list for main elements
buttons = []
for i in range(7):
temp = []
for j in range(18):
but = Button(main_elem,text=main[18*i j],width=10,bg='#f0f0f0')
but.grid(row=i,column=j)
temp.append(but)
buttons.append(temp)
# Creating a 2x15 table of buttons for secondary elements
for i in range(2):
for j in range(15):
text = sec[15*i j]
if i == 0: # If row 1 then different color
Button(sec_elem,text=text,width=10,bg=rare_m_col).grid(row=i,column=j)
else:
Button(sec_elem,text=text,width=10,bg=act_col).grid(row=i,column=j)
# Manually pick out main elements from the table
non_metals = buttons[0][0],buttons[1][12:16],buttons[2][13:16],buttons[3][14:16],buttons[4][15]
alk_metals = [row[0] for row in buttons[1:]]
alk_ea_metals = [row[1] for row in buttons[1:]]
halogens = [row[16] for row in buttons[1:]]
noble_gases = [row[-1] for row in buttons[:]]
transition_met = [buttons[x][3:12] for x in range(3,7)]
metals = buttons[6][12:16],buttons[5][12:16],buttons[4][12:15],buttons[3][12:14],buttons[2][12]
rare_metals = [row[2] for row in buttons[3:6]]
actinoid = buttons[-1][2]
plain_but = buttons[0][1:-1],buttons[1][2:12],buttons[2][2:12]
# Change colors for those main element buttons
actinoid['bg'] = act_col
for i in alk_metals: i['bg'] = alk_m_col
for i in alk_ea_metals: i['bg'] = alk_ea_col
for i in halogens: i['bg'] = halogen_col
for i in noble_gases: i['bg'] = noble_g_col
for i in rare_metals: i['bg'] = rare_m_col
for i in transition_met:
for j in i:
j['bg'] = trans_m_col
for i in non_metals:
if isinstance(i,list):
for j in i:
j.config(bg=non_m_col)
else:
i.config(bg=non_m_col)
for i in metals:
if isinstance(i,list):
for j in i:
j.config(bg=metals_col)
else:
i.config(bg=metals_col)
for i in plain_but:
for j in i:
j['relief'] = 'flat'
Button(root,text='EXIT',command=root.destroy).pack(pady=10)
root.mainloop()
我已經對代碼進行了注釋,以使其更易于理解。切片部分可能看起來有點復雜,因為 python list 不支持 2D 切片。一種方法是創建一個numpy陣列并將坐標存盤到它上面,然后根據坐標檢索相應的按鈕物件,可能是更長的代碼,但由于numpy支持 2D 切片,它會使切片更容易和易于理解。
GUI的最終輸出:

編輯:

作為該表的可點擊版本:
class Element(tk.Frame):
la_offset = 2;ac_offset=2;offset=2
def __init__(self,master,symbol,**kwargs):
tk.Frame.__init__(self,master,
relief = 'raised')
self.kwargs = kwargs
self.command= kwargs.pop('command', lambda:print('No command'))
self.WIDTH,self.HEIGHT,self.BD = 100,100,3
self.CMP = self.BD*2
bg = kategorie_farben.get(kwargs.get('elementkategorie'))
self.configure(width=self.WIDTH,height=self.HEIGHT,bd=self.BD,
bg=bg)
self.grid_propagate(0)
self.idx = tk.Label(self,text=kwargs.get('index'),bg=bg)
self.u = tk.Label(self,text=kwargs.get('atommasse'),bg=bg)
self.name = tk.Label(self,text=kwargs.get('name'),bg=bg)
self.symb = tk.Label(self,text=symbol,font=('bold'),fg=self.get_fg(),bg=bg)
self.e = tk.Label(self,text=kwargs.get('elektronegativit?t'),bg=bg)
self.d = tk.Label(self,text=kwargs.get('dichte'),bg=bg)
self.grid_columnconfigure(1, weight=2)
self.grid_rowconfigure(1, weight=2)
self.idx.grid(row=0,column=0,sticky='w')
self.u.grid(row=0,column=2,sticky='e')
mid_x = self.WIDTH/2-self.name.winfo_reqwidth()/2
mid_y = self.HEIGHT/2-self.name.winfo_reqheight()/2
offset= 15
self.name.place(in_=self,x=mid_x-self.CMP,y=mid_y-self.CMP offset)
mid_x = self.WIDTH/2-self.symb.winfo_reqwidth()/2
mid_y = self.HEIGHT/2-self.symb.winfo_reqheight()/2
self.symb.place(in_=self,x=mid_x-self.CMP,y=mid_y-self.CMP-offset/2)
self.e.grid(row=2,column=0,sticky='w')
self.d.grid(row=2,column=2,sticky='e')
r,c = kwargs.pop('periode'),kwargs.pop('gruppe')
if c in ('La','Ac'):
if c == 'La':
c =Element.la_offset Element.offset;Element.la_offset =1
r = self.offset
if c == 'Ac':
c =Element.ac_offset Element.offset;Element.ac_offset =1
r = Element.offset
self.grid(row=r,column=c,sticky='nswe')
self.bind('<Enter>', self.in_active)
self.bind('<Leave>', self.in_active)
self.bind('<ButtonPress-1>', self.indicate)
self.bind('<ButtonRelease-1>', self.execute)
[child.bind('<ButtonPress-1>', self.indicate) for child in self.winfo_children()]
[child.bind('<ButtonRelease-1>', self.execute) for child in self.winfo_children()]
def in_active(self,event):
if str(event.type) == 'Enter': self.flag = True
if str(event.type) == 'Leave':
self.flag = False;self.configure(relief='raised')
def indicate(self,event):
self.configure(relief='sunken')
def execute(self,event):
if self.flag: self.command();self.configure(relief='raised')
else: self.configure(relief='raised')
def get_fg(self):
if self.kwargs.get('aggregatzustand') == 'fest': return 'black'
if self.kwargs.get('aggregatzustand') == 'flüssig': return 'blue'
if self.kwargs.get('aggregatzustand') == 'gasf?rmig': return 'red'
if self.kwargs.get('aggregatzustand') == 'n.A': return 'grey'
def test():
print('testing..')
for idx,symbol in enumerate(symbols):
kwargs = {}
for k,v in zip(keywords,values[idx]):
kwargs.update({k:v})
Element(root,symbol,command=test,**kwargs)
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/398967.html
