【问题标题】:Python issue editing tkinter canvas items in a 2darrayPython问题在二维数组中编辑tkinter画布项目
【发布时间】:2013-05-20 18:25:26
【问题描述】:

我使用树莓派作为更复杂设备的通信前端。我正在用 python 编写代码,并包含一个 gui 来显示通过它的信息。

我的问题涉及大小为 4x4 的画布文本项网格,由二维数组 dataText[][] 引用。我正在使用itemconfigure() 编辑项目以更新显示的数据。

问题:当我更新 dataText[y][x] 时,无论数字如何,它都会更新位置 (3,x) 处的项目。

演示代码:

from Tkinter import *
from ttk import Style

#gui class (tkinter loop)
class UI(Frame):
    #data value field
    dataText = [[0]*4]*4

    def __init__(self, parent):
        Frame.__init__(self, parent)

        self.parent = parent

        self.initUI()

    def initUI(self):

        #sets up the main window
        self.parent.title("Power Converter Controller")
        self.style = Style()
        self.style.theme_use("default")
        self.pack(fill=BOTH, expand=YES)

        #configures padding along columns and rows
        for i in range(4):
            self.columnconfigure(i, pad=3, weight=1)
        for i in range(7):
            self.rowconfigure(i, pad=3, weight=1)

        #creates a canvas at the top of the window. The canvas is used for
        #displaying data
        self.display = Canvas(self, width=600, height=170)
        self.display.grid(column=0, row=0, columnspan=4, rowspan=4)

        #draws canvas items that can be updated
        self.dynamicCanvasItems(self.display)

    def dynamicCanvasItems(self, canvas):

        #initializes the grid text handles
        for i in range(4):
            for j in range(4):
                self.dataText[i][j] = canvas.create_text(75*(j+1),25*(i+1),text = data[i][j], font=("Helvetica",20))

        for i in range(4):
            for j in range(4):
                self.display.itemconfigure(self.dataText[i][j], text=5)

def main():

    global root
    global data

    #initialize 2d data array
    data = [[x]*4 for x in xrange(4)]

    #initialize the ui loop
    root = Tk()
    root.geometry("600x300+600+300")
    ui = UI(root)

    #enter the ui loop
    root.mainloop()

if __name__ == '__main__':
    main()

整个程序比较大,所以我删掉了不相关的部分。我确保编辑部分对问题没有影响(通过禁用它们并检查问题是否改变)。

dynamicCanvasItems() 方法中,小部件已正确设置。如果禁用第二个双 for 循环,它会显示:

0    0    0    0
1    1    1    1
2    2    2    2
3    3    3    3

所以第二个双 for 循环应该用 5 覆盖所有小部件。但是,会发生这种情况:

0    0    0    0
1    1    1    1
2    2    2    2
5    5    5    5

有人知道为什么吗?

【问题讨论】:

    标签: python canvas tkinter multidimensional-array


    【解决方案1】:

    这是因为您的初始化代码正在创建一个列表列表,其中每个子列表都是对同一对象的引用。您没有包含四个不同子列表的列表,您有一个包含对同一列表的四个引用的列表。

    为了证明这一点,请在初始化 dataText 之后添加以下内容:

    print [id(x) for x in dataText]
    

    您会看到所有四个列表都具有完全相同的内部 id,这意味着它们都引用完全相同的列表。

    比较当您将初始化代码更改为此时会发生什么:

    dataText = [
        [0,0,0,0],
        [0,0,0,0],
        [0,0,0,0],
        [0,0,0,0]
        ]
    

    在上面,您明确创建了四个唯一列表,每个列表都有四个唯一值。

    【讨论】:

      猜你喜欢
      • 2023-03-12
      • 2011-09-08
      • 2015-01-15
      • 2022-11-16
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多