tkinter python 中自定义颜色格式的高效代码

Vis*_*10B 5 python tkinter

所以,我试图创建一个元素周期表,它几乎是从外部有效完成的。但是,我不明白是否有任何方法可以以相同的方式填充各个按钮的颜色。有人可以帮我解决这个问题吗?

下面是我的代码:

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()
Run Code Online (Sandbox Code Playgroud)

进一步说明:如果有人能告诉我如何为各个按钮着色(例如绿色为卤素、蓝色为金属、红色为氢)以及如何为每个按钮命令创建顶层,我将不胜感激。

Coo*_*oud 5

我用一些更好的方法来重写您的代码来创建表。我的想法是挑选出属于一系列类型的按钮,然后循环遍历这些按钮并将其颜色更改为这些类型。

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()
Run Code Online (Sandbox Code Playgroud)

我对代码进行了注释,以使其更容易理解。切片部分可能看起来有点复杂,因为 python list 不支持 2D 切片。一种方法是创建一个numpy数组并将坐标存储在其中,然后根据坐标检索相应的按钮对象,代码可能会更长,但由于支持 2D 切片,因此会使切片更加容易和易于理解numpy

GUI的最终输出: SS

编辑: 是一个更高级且不那么复杂的元素周期表