簡體   English   中英

Python 從帶有參數的列表中創建 tkinter class 的唯一實例

[英]Python create unique instances of a tkinter class from a list with parameters

我正在幫助清理高級設計項目的一些代碼。 學生有一個 python 應用程序,它使用 tkinter 創建用於庫存控制和自動售貨產品的 GUI。 我不想發布大量代碼,但希望描述我正在嘗試做的事情。

以下內容的描述:BinA、BinB、BinC 和 BinD 都是相同的,但傳入了唯一的變量,在名為 pages.py 的新文檔中創建了一個 bin class。 這些是在主程序的底部使用它們的變量創建的。 然后我將它們與應用程序將瀏覽的其他頁面一起放入 framesList 中。 列表中的所有其他框架目前都是代碼中唯一的硬編碼類,或者如果我們讓它工作,我們將希望應用我正在努力解決的解決方案。

當 Bin(AD) 都具有唯一的硬編碼自命名類時,除了我們識別的幾個參數之外,它們具有相同的代碼,屏幕導航按預期運行,但創建 4 個 pages.bin 實例並遍歷框架結果列表只有看起來只有最后創建的變量的 4 pages.bin。 您可以for F in frameList:調用了 show self.show_frame(BinA) ,但是 LinkList 中的第一個元素是一個字符串,它在屏幕上填充了一個 label。 這個 label 只顯示了 Pages.bin 的最后一幀是什么。 類型。 其他屏幕均已正確創建且為 function。在這種情況下,只需導航回屏幕 Bin(?) 始終表現得像 BinD。 如果我以相反的順序創建它們 D,C,B,A 那么 BinA 是所有四個的結果。

我懷疑正在發生的事情是我們只創建了一個 pages.Bin 實例,並for F in frameList:每個循環中簡單地覆蓋它:但另一個沒問題,因為它們都是唯一的類。

import tkinter as tk
from tkinter import *
import random
import time
import csv
import openpyxl
import pages

#get Display Size
root = tk.Tk()
screen_width = root.winfo_screenwidth() #1440
screen_height = root.winfo_screenheight() #900
#Close the popup
root.destroy()

print('Width: %i px, height: %i px' %(screen_width, screen_height))


#Create the main Application
class CMGUI(tk.Tk):
    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)
        tk.Tk.wm_title(self, "CMA: AutoBox")
        tk.Tk.wm_resizable(self,0,0)
        tk.Tk.wm_overrideredirect(self,False)#True) //Use this on the final
        container = tk.Frame(self)       
        container.pack(side="top", fill="both", expand=True)
        container.grid_columnconfigure(0, weight=1)
        container.grid_rowconfigure(0, weight=1)
        

        self.frames = {}

        #Declart the Objects

        # Put them in a List
        frameList =    [[BinA       ,BinA_linksList],
                        [BinB       ,BinB_linksList],
                        [BinC       ,BinC_linksList],
                        [BinD       ,BinD_linksList],
                        [HomePage   ,None],
                        [PPE        ,None],
                        [Weld       ,None],
                        [Misc       ,None],
                        [Set        ,None],
                        [PPE2       ,None],
                        [Weld2      ,None],
                        [Misc2      ,None],
                        [AllItems   ,None],
                        [BinType    ,None],
                        [Inventory  ,None],
                        [LoginPage  ,None]]

        for F in frameList:             
        #   frame = F(parent=container, controller=self)
            frame = F[0](container, self, F[1])
            self.frames[F[0]] = frame
            frame.grid(row=0, column=0, sticky="nsew")
            frame.configure(bg='deepskyblue')


        self.show_frame(BinA) 
....
class LoginPage(tk.Frame):
     def __init__(self, parent, controller,*args):
        tk.Frame.__init__(self, parent)
        ....

class HomePage(tk.Frame):
    def __init__(self, parent, controller,*args):
        tk.Frame.__init__(self, parent)
        ....

class AllItems(tk.Frame):
    def __init__(self, parent, controller,*args):
        tk.Frame.__init__(self, parent)
        .....

ALLOT OF other CODE creating the other page classes like BinType, HomePage, PPE, and more
....

#Create 4 pages for bins
# Bin? = pages.Bin
# Bin?_linkList = ["Label"  ,return_Link ,Link_1    ,Link_2     ,Link_3     ,Link_4]

BinA = pages.Bin
BinA_linksList = ["Bin A"   ,BinType    ,HomePage   ,PPE        ,PPE        ,PPE]

BinB = pages.Bin
BinB_linksList = ["Bin B"   ,BinType    ,PPE        ,HomePage   ,PPE    ,PPE]

BinC = pages.Bin
BinC_linksList = ["Bin C"   ,BinType    ,PPE        ,PPE        ,HomePage   ,PPE]

BinD = pages.Bin
BinD_linksList = ["Bin D"   ,BinType    ,PPE        ,PPE        ,PPE    ,HomePage]


w = str(screen_width)
h = str(screen_height)
z = str("+0+0")
screenres = w+'x'+h+z

app = CMGUI()
app.geometry(screenres)
app.mainloop()
root.destroy

頁面.py

import tkinter as tk

class Bin(tk.Frame):

    def __init__(self, parent, controller, data):
     
        print(data[0])
        tk.Frame.__init__(self, parent)
        
        # Header Label        
        tk.Label(self, font=('times', 50, 'bold'), 
            text=data[0], fg="deepskyblue", bd=20, anchor='center', 
            bg="black", relief="ridge").place(anchor = "n", relx = .5, y =0)
        
        # Footer Label
        tk.Label(self, font=('times',22,'bold'), 
            text="Page 1", bg="deepskyblue", fg="black").place(anchor = "s", relx = .5, rely = .95)

        #Buttons:
        #mylist =   [["Title"]                  , page      , "anchor"  , %x    ,  %y   ],
        btnList =   [["Search By\n Bin Type"    , data[0]   , "ne"      , .95   , .05   ],
                    ["Back to\n Categories"     , data[1]   , "nw"      , .05   , .05   ]]
                    
        for b in btnList:
            tk.Button(self, padx=5, pady=5, bd=16, fg="white", font=('times',24,'bold'), width=8, height=2,
                  text=b[0], bg="black", relief="raised",
                  command = lambda i=b[1]: controller.show_frame(i)).place(anchor = b[2],relx = b[3], rely = b[4])

        btnList2 =   [["Item 1"   , data[2]   , "se"      , .5   , .5   ],
                     ["Item 2"    , data[3]   , "sw"      , .5   , .5   ],
                     ["Item 3"    , data[4]   , "ne"      , .5   , .5   ],
                     ["Item 4"    , data[5]   , "nw"      , .5   , .5   ]]
                
        for b in btnList2:
            tk.Button(self, padx=5, pady=5, bd=16, fg="white", font=('times',24,'bold'), width=9, height=3,
                  text=b[0], bg="black", relief="raised",
                  command = lambda i=b[1]: controller.show_frame(i)).place(anchor = b[2],relx = b[3], rely = b[4])

BinA、BinB、BinC 和 BinD 完全相同 object:Bin。 將您的代碼歸結為最簡單的術語,您期望 output 是什么?

data = 'spam'
BinA = data
BinB = data
BinC = data
BinD = data

frames = {}
for F in (BinA, BinB, BinC, BinD):
    frames[F] = 42

print(frames) # what do you expect this to print? 

試試看,你就會明白你的問題。

簡單的解決方案是更換

BinA = pages.Bin

class BinA(pages.Bin): pass

從而創造出獨一無二的object。

但這根本不干凈。 要清理它,您可以選擇一個不同的指標來存儲您的頁面,同時移動到現代 inheritance 樣式並刪除無用的 controller 框架。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM