代码之家  ›  专栏  ›  技术社区  ›  Eleshar

循环数组停止增加索引(Orig:Message小部件文本随机不刷新)

  •  0
  • Eleshar  · 技术社区  · 9 年前

    Report Data Start Time:;00:00 25/08/2016Report;Va1;Val2;Val3;Val4;Val5;Val6;Val7
    X;6;4;0;0;32;3;0.8125
    Y;2;1;0;0;0;0;0
    Z;5;1;0;0;0;0;0
    [empty last line]
    

    在tkinter中,我创建了一个GUI,它可以读取数据并以某种表格的形式实时显示。这些小部件是按程序生成的,并以预定义的名称存储在一个集合中,稍后会基于该名称调用它们,并修改其内容。 然而,当数据被读取并放入窗口小部件时,一些看似随机的单元格是空的。当我说随机时,它实际上是相当一致的(col2、row2和col5到7,row2到3),但是当我以某种方式更改报告文件时,新值可能会出现,也可能不会出现(这确实是非常随机的)。

    import tkinter as tk
    
    class MainApplication(tk.Frame):
    
        global SkillWidgets
        SkillWidgets = {}
    
    
        def __init__(self, parent, *args, **kwargs):
            tk.Frame.__init__(self, parent, *args, **kwargs)       
            self.parent = parent
            self.create_stuff()
            self.refresh()
    
    
        def create_stuff(self):        
            screen_width = tkGUI.winfo_screenwidth()
            screen_height = tkGUI.winfo_screenheight()
            iSW = screen_width/1000
            iSH = screen_height/1000
    
            tkFrSkills = tk.Frame(tkGUI)
            tkFrSkills.place(x=(100*iSW)+20, y=20+(50*iSH), bordermode=tk.INSIDE, height=screen_height/2-(100+50*iSH), width=screen_width)
    
            for iRow in range(1,4):
                for iCol in range(1,8):
                    tkMsg = tk.Message(tkFrSkills, text="", font=("Arial", 36), relief = tk.GROOVE, bd = 2, width = 100)
                    tkMsg.place (x=((iCol-1)*100*iSW), y=(75*iRow*iSH)-(75*iSH), bordermode=tk.INSIDE, width = 100*iSW, height = 75*iSH)
                    SkillWidgets[(iRow,iCol)] = tkMsg
    
    
    
        def refresh(self):
            fSkills = open("report.txt")
            sSkContents = fSkills.read()
            fSkills.close()
    
            SkLines = sSkContents.split("\n")
            del(SkLines[len(SkLines)-1])
    
            iSkRow = 0
            for sSkLine in SkLines:  
                if "X" in sSkLine:
                    iSkRow = 1
                if "Y" in sSkLine:
                    iSkRow = 2
                if "Z" in sSkLine:
                    iSkRow = 3       
    
                if iSkRow > 0:
                    SkItems = sSkLine.split(";")
                    SkItems[1], SkItems[2], SkItems[3], SkItems[4] = SkItems[2], SkItems[4], SkItems[1], SkItems[3]
                    SkItems[2] = str(int(SkItems[3])-int(SkItems[1]))              
                    del(SkItems[0])                                      
                 ***print(SkLines[iSkRow])
    
                    for sSkItem in SkItems:
    
                        iSkCol = SkItems.index(sSkItem)+1
                    ****print("Row=",iSkRow,"Col=",iSkCol,"sSkItem=",sSkItem)
                   *****print("Row=",iSkRow,"Col=",iSkCol,"widget text =", SkillWidgets[(iSkRow,iSkCol)].cget("text"))
                        SkillWidgets[(iSkRow,iSkCol)].config(text = sSkItem)
                    ****print("Row=",iSkRow,"Col=",iSkCol,"sSkItem=",sSkItem)
                   *****print("Row=",iSkRow,"Col=",iSkCol,"widget text =", SkillWidgets[(iSkRow,iSkCol)].cget("text"))
                        print("----------")
    
    
            self.after(1000,self.refresh)
    
    if __name__ == "__main__":
        tkGUI = tk.Tk()
        tkGUI.attributes("-fullscreen", True)
        MainApplication(tkGUI).pack(side="top", fill="both", expand=True)
        tkGUI.mainloop()
    

    编辑: 我忘了提到我试图打印我输入的值(代码已调整-我用一些星号突出显示了这些地方

    ***此打印正确地给出了相关行,但由于某种原因,它在循环中运行了两次,给出了

    X;6;4;0;0;32;3;0.8125
    Y;2;1;0;0;0;0;0
    Z;5;1;0;0;0;0;0
    

    ****这个打印正确地给出了我想输入到小部件的值

    *****这张照片正成为问题的根源: a) 如果输入值为“1”,循环根本不会经过2:2,但只给出了2:1两次,第一次打印将小部件的值显示为“1 b) 如果输入值为“2”或更大,则按预期工作-循环按预期经过2:1、2:2、2:3

    Row= 2 Col= 1 sSkItem= 1
    Row= 2 Col= 1 widget text = 
    Row= 2 Col= 1 sSkItem= 1
    Row= 2 Col= 1 widget text = 1
    ----------
    Row= 2 Col= 1 sSkItem= 1
    Row= 2 Col= 1 widget text = 1
    Row= 2 Col= 1 sSkItem= 1
    Row= 2 Col= 1 widget text = 1
    ----------
    

    Row= 2 Col= 1 sSkItem= 1
    Row= 2 Col= 1 widget text = 
    Row= 2 Col= 1 sSkItem= 1
    Row= 2 Col= 1 widget text = 1
    ----------
    Row= 2 Col= 2 sSkItem= 3
    Row= 2 Col= 2 widget text = 
    Row= 2 Col= 2 sSkItem= 3
    Row= 2 Col= 2 widget text = 3
    ----------
    

    c) 在这两种情况下,循环都不适用于第2行;3至5至7列

    编辑2:

    编辑3: 我似乎正在找到原因……此时,对于第2行和第3行,它只是在第5次迭代中停止增加索引(索引为4的项未加载,而是再次加载索引为3的项)

                for sSkItem in SkItems:
                    print(SkItems)
                    print("item3: ", SkItems[3])
                    print("item4: ", SkItems[4])
                    print("item5: ", SkItems[5])
                    print("item6: ", SkItems[6])
                    iSkCol = SkItems.index(sSkItem)
                    print("index", iSkCol)
                    print("Row=",iSkRow,"Col=",iSkCol,"sSkItem=",sSkItem)
                    print("Row=",iSkRow,"Col=",iSkCol,"widget text =", SkillWidgets[(iSkRow,iSkCol)].cget("text"))
                    SkillWidgets[(iSkRow,(iSkCol))].config(text = sSkItem)
                    print("Row=",iSkRow,"Col=",iSkCol,"sSkItem=",sSkItem)
                    print("Row=",iSkRow,"Col=",iSkCol,"widget text =", SkillWidgets[(iSkRow,iSkCol)].cget("text"))
    

    结果打印输出如下:

    ['1', 1, '2', '0', '0', '0', '0']
    item3:  0
    item4:  0
    item5:  0
    item6:  0
    index 1
    Row= 1 Col= 1 sSkItem= 1
    Row= 1 Col= 1 widget text = 
    Row= 1 Col= 1 sSkItem= 1
    Row= 1 Col= 1 widget text = 1
    ---
    ['1', 1, '2', '0', '0', '0', '0']
    item3:  0
    item4:  0
    item5:  0
    item6:  0
    index 2
    Row= 1 Col= 2 sSkItem= 2
    Row= 1 Col= 2 widget text = 
    Row= 1 Col= 2 sSkItem= 2
    Row= 1 Col= 2 widget text = 2
    ---
    ['1', 1, '2', '0', '0', '0', '0']
    item3:  0
    item4:  0
    item5:  0
    item6:  0
    index 3
    Row= 1 Col= 3 sSkItem= 0
    Row= 1 Col= 3 widget text = 
    Row= 1 Col= 3 sSkItem= 0
    Row= 1 Col= 3 widget text = 0
    ---
    ['1', 1, '2', '0', '0', '0', '0']
    item3:  0
    item4:  0
    item5:  0
    item6:  0
    index 3
    Row= 1 Col= 3 sSkItem= 0
    Row= 1 Col= 3 widget text = 0
    Row= 1 Col= 3 sSkItem= 0
    Row= 1 Col= 3 widget text = 0
    ---
    
    1 回复  |  直到 9 年前
        1
  •  0
  •   Resurrection    9 年前

    我认为您的问题在于错误使用 for 循环,特别是

    for sSkItem in SkItems:
        iSkCol = SkItems.index(sSkItem)+1
    

    将为您提供索引 第一次出现 属于 sSkItem 在里面 SkItems 而不是你毫无疑问期望/想要的循环中当前项目的索引。如果有任何重复的项目(如您所见),这将中断。

    要修复此问题,可以使用自己的计数器跟踪索引,例如:

    currentIndex = 0
    
    for sSkItem in SkItems:
        iSkCol = currentIndex
        currentIndex += 1
    

    或者使用循环的正常范围进行迭代 索引 而不是物品。