Как связать несколько кнопок с одним текстовым виджетом в tkinter? - PullRequest
0 голосов
/ 29 сентября 2018

Я пытаюсь выучить tkinter, и я хотел написать простую игру о ножницах из каменной бумаги, где есть окно с 3 кнопками и одним текстовым виджетом.

Я бы хотел иметь возможность нажать любую из кнопок, чтобы сообщение появилось в текстовом поле, затем нажать другую кнопку, текстовое поле, чтобы очистить и отобразить новое сообщение, связанное со вторымкнопка и тд.

Из просмотренных мною учебников я знаю, что могу передать текстовый виджет с функцией функции в качестве аргумента в параметре команды кнопки. Я знаю, что могу создать 3 функции с текстовым полем, по одной для каждой кнопки (отображение по одному), но это, вероятно, не правильный путь.Вот что у меня есть:

import tkinter as tk

root = tk.Tk()
root.title("Rock Paper Scissors")
root.geometry("420x200")

def Rock():
    rockText = "Paper!"
    return rockText

def Paper():
    paperText = "Scissors!"
    return paperText

def Scissors():
    scissorsText = "Rock!"
    return scissorsText

def display():

    textDisplay = tk.Text(master = root, height = 10, width = 50)
    textDisplay.grid(row = 1, columnspan = 5)
    textDisplay.insert(tk.END, Rock())

buttonRock = tk.Button(text = "Rock", command = display).grid(row = 0, column = 1, padx = 10)
buttonPaper = tk.Button(text = "Paper").grid(row = 0, column = 2, padx = 10)
buttonScissors = tk.Button(text = "Scissors").grid(row = 0, column = 3, padx = 10)

root.mainloop()

Любая помощь будет оценена по достоинству.

Правка: Вторая мысль - я могу представить, что усложняю это для себя, пытаясь заставить игруработать таким образом.С помощью случайного модуля я смог бы выбрать одну функцию для выбора компьютера со списком и сохранить случайный выбор в параметре, а затем вернуть значение в функцию отображения.

1 Ответ

0 голосов
/ 29 сентября 2018

Так что, если я правильно понял, вы просто хотите нажать кнопку, чтобы изменить текст в Text-виджете.Для этого у вас есть два простых и довольно похожих варианта.Сначала нужно определить 3 функции, как вы это сделали, и позволить им напрямую изменять текст.Второй вариант - создать одну функцию, которая изменяет текст в соответствии с заданным.Обратите внимание, что во втором случае нам придется использовать lambda, который довольно хорошо работает в небольших проектах, но снижает эффективность ваших программ, когда они становятся больше.

Первый вариант:

import tkinter as tk

class App:
    def __init__(self):
        root=tk.Tk()
        root.title("Rock Paper Scissors")
        root.geometry("420x200")
        self.text=Text(root)
        self.text.grid(row=1,columnspan=5)
        tk.Button(root,text="Rock",command=self.Rock).grid(row=0,column=1,padx=10)
        tk.Button(root,text="Paper",command=self.Paper).grid(row=0,column=2)
        tk.Button(root,text="Scissors",command=self.Scissors).grid(row=0,column=3,padx=10)
        root.mainloop()

    def Rock(self):
        text="Paper!"
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

    def Paper(self):
        text="Scissors!"
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

    def Scissors(self):
        text="Rock!"
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

if __name__=='__main__':
    App()

Второй вариант:

import tkinter as tk

class App:
    def __init__(self):
        root=tk.Tk()
        root.title("Rock Paper Scissors")
        root.geometry("420x200")
        self.text=Text(root)
        self.text.grid(row=1,columnspan=5)
        tk.Button(root,text="Rock",command=lambda: self.updateText('Paper!')).grid(row=0,column=1,padx=10)
        tk.Button(root,text="Paper",command=lambda: self.updateText('Scissors!')).grid(row=0,column=2)
        tk.Button(root,text="Scissors",command=lambda: self.updateText('Rock!')).grid(row=0,column=3,padx=10)
        root.mainloop()

    def updateText(self,text):
        self.text.delete(0,END) #delete everything from the Text
        self.text.insert(0,text) #put the text in

if __name__=='__main__':
    App()

Некоторые небольшие заметки от меня здесь:

  1. Если вы используете grid, pack или place прямо на самом виджете, выне будет присваивать виджет переменной, но возвращает функцию grid, pack или place, которая равна None.Поэтому лучше сначала назначить виджет переменной, а затем использовать менеджер геометрии, как я сделал для Text -widget.
  2. После этого вам не нужно дополнительно устанавливать заголовок с помощью функции title.Вы можете установить его с помощью className -аргумента в Tk.
  3. Если вы работаете с tkinter, то это нормально делать функционально, а использовать класс для создания графического интерфейса.
  4. При создании новых виджетов всегда обязательно передайте им переменную для корневого окна.Они также получат его сами, если вы этого не сделаете, но для этого нужно больше ненужных фоновых действий, и если у вас открыто более одного Tk -окна, оно автоматически выберет то, которое вы не хотите использовать.
  5. И один небольшой совет в конце: если вы хотите узнать больше обо всех виджетах tkinter, попробуйте http://effbot.org/tkinterbook/tkinter-index.htm#class-reference.

Я надеюсь, что это полезно.Удачного программирования!

РЕДАКТИРОВАТЬ: Я только что видел ваше редактирование с помощью модуля случайныхВ этом случае я бы рекомендовал второй вариант.Просто удалите text -аргумент из updateText и замените lambda: self.updateText(...) на self.updateText()updateText вы добавляете случайную вещь из списка, которую вы упомянули.: D

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...