【问题标题】:refresh Tkinter window in Python在 Python 中刷新 Tkinter 窗口
【发布时间】:2020-04-14 02:36:21
【问题描述】:

我制作了一个简单的“游戏 9”,它在纯 Python 中运行良好。现在我想在 Tkinter 窗口中做同样的事情。 我正在尝试通过按键刷新 Tkinter 窗口 - 当我按下数字 (1-8) 时,我将矩阵设置为不同的数字,我想刷新窗口。不幸的是,我不知道如何做好。我使用了 window.update() 和 window.destroy() 但这个解决方案很糟糕。您能否帮助如何在不使用 window.destroy() 的情况下刷新我的 Tkinter 窗口? 我是 Tkinter 和 Python 的新手 :)

import random
import tkinter as tk
from time import sleep
import keyboard


x,px,py,px2,py2 = 0,0,0,0,0
matrix = [[0,0,0],[0,0,0],[0,0,0]]

# generate 9 unique numbers (0 to 8) and insert them into matrix 
z = random.sample(range(0,9),9)

matrix[0] = [(z[0]), (z[1]), (z[2])]
matrix[1] = [(z[3]), (z[4]), (z[5])]   
matrix[2] = [(z[6]), (z[7]), (z[8])]

def printmatrix():

    label1 = tk.Label(text = matrix[0])
    label1.grid(column = 1, row = 1)
    label2 = tk.Label(text = matrix[1])
    label2.grid(column = 1, row = 2)
    label3 = tk.Label(text = matrix[2])
    label3.grid(column = 1, row = 3)




# check win
def check_win():
    if matrix[0] == [1,2,3] and matrix[1] == [4,5,6] and matrix[2] == [7,8,0]:
        label4 = tk.Label(text = "you won !!!")
        label4.grid(column = 0, row = 6)
        window.update()
        sleep (5)
        exit ()


while __name__ == '__main__':
    window = tk.Tk()
    window.title("GAME 9")
    window.geometry("300x300")

    printmatrix()
    window.update()  


    check_win()

    # read key 1-8

    if keyboard.read_key() == "1":
        x = 1
    if keyboard.read_key() == "2":
        x = 2
    if keyboard.read_key() == "3":
        x = 3
    if keyboard.read_key() == "4":
        x = 4
    if keyboard.read_key() == "5":
        x = 5
    if keyboard.read_key() == "6":
        x = 6
    if keyboard.read_key() == "7":
        x = 7
    if keyboard.read_key() == "8":
        x = 8



# check position of "0"
    for pozx,j in enumerate(matrix):
        for pozy,l in enumerate(j):
            if l==0:
                px = int(pozx)
                py = int(pozy)


# check position of moved number
    for pozx2,j in enumerate(matrix):
        for pozy2,l in enumerate(j):
            if l==x:
                px2 = int(pozx2)
                py2 = int(pozy2)


# check if the moved number is on the right place  (if we can use it)
    if  (px == px2 or py == py2) and ((py+1 or py-1 == py2) or (px+1 or px-1 == px2)):
        if (px == 0 and px2 == 1) or (px == 1 and px2 == 2) or (px == 1 and px2 == 0) or (px == 2 and px2 == 1) or (py == 0 and py2 == 1) or (py == 1 and py2 == 2) or (py == 1 and py2 == 0) or (py == 2 and py2 == 1):


            matrix[px2][py2] = 0
            matrix[px][py] = x
            printmatrix()


        else:
            label5 = tk.Label(text = "wrong move, try again")
            label5.grid(column = 0, row = 5)
            window.update()
            sleep(2)
            printmatrix()


    else:
        label6 = tk.Label(text = "wrong move, try again")
        label6.grid(column = 0, row = 4)
        window.update()
        sleep(2)
        printmatrix()


    window.destroy()  
    window.mainloop()

【问题讨论】:

  • 不要使用模块 keyboardtkinter 方法将函数绑定到按下的键 - root.bind("1", function_name) 并在此函数内部设置变量。您将必须了解所有 GUI 框架的工作原理并重写它。
  • 在开始时创建所有标签,之后只更改标签中的文本。不要在同一个地方一遍又一遍地创建标签,因为之前的标签仍在窗口中并占用内存。

标签: python tkinter refresh


【解决方案1】:

我没有测试到最后,但它使用了大多数 GUI 中使用的方法。

它将功能绑定/分配给键,因此运行 move(number) 并移动数字。

它在开始时创建标签,之后只更改标签中的文本。

它不需要任何update,因为它会自动更新。

顺便说一句:就像在数学中使用的矩阵一样,我使用[row][column],这意味着[y][x],而不是[x][y]

import random
import tkinter as tk
import time

# generate 9 unique numbers (0 to 8) and insert them into matrix 
z = random.sample(range(0,9),9)

matrix = [
    [(z[0]), (z[1]), (z[2])],
    [(z[3]), (z[4]), (z[5])],
    [(z[6]), (z[7]), (z[8])],
]    
#print(matrix)

def update_labels():
    for row_matrix, row_labels in zip(matrix, labels):
        for item, label in zip(row_matrix, row_labels): 
            label["text"] = item


def move(number):
    #print(number)

    # find position of "0" and moved number
    for y, row in enumerate(matrix):
        for x, cell in enumerate(row):
            if cell == 0:
                zero_x = x
                zero_y = y
            elif cell == number:
                number_x = x
                number_y = y

    # check if the moved number is on the right place  (if we can use it)
    diff_x = abs(zero_x - number_x)
    diff_y = abs(zero_y - number_y)
    if (diff_x == 0 and diff_y == 1) or (diff_x == 1 and diff_y == 0):
            matrix[number_y][number_x] = 0
            matrix[zero_y][zero_x] = number
    else:
        message_label['text'] = "wrong move, try again"

    update_labels()
    check_win()

def check_win():
    if matrix == [[1,2,3], [4,5,6], [7,8,0]]:
        message_label['text'] = "you won !!!"
        time.sleep(5)
        exit()

if __name__ == '__main__':
    window = tk.Tk()
    window.title("GAME 9")
    window.geometry("300x300")

    # create labels
    labels = []
    for y in range(1, 4):
        row = []
        for x in range(1, 4): 
            label = tk.Label(window)
            label.grid(column=x, row=y)
            row.append(label)
        labels.append(row)

    # label for messages        
    message_label = tk.Label(window)
    message_label.grid(column=0, row=4, columnspan=5)

    # fill labels at start
    update_labels()

    # bind keys to function
    for i in range(1, 10):
        window.bind(str(i), lambda event, x=i:move(x))

    # start program and show window
    window.mainloop()

【讨论】:

  • 感谢您的回复,有些事情我现在更清楚了。而且我可以看到您的代码处于另一个级别(与我的相比)。我必须学习很多:)
猜你喜欢
  • 1970-01-01
  • 2017-04-24
  • 2010-12-29
  • 2020-05-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-27
相关资源
最近更新 更多