Python Tkinter: дождитесь ввода пользователя, прежде чем продолжить с MainLoopPython

Программы на Python
Ответить Пред. темаСлед. тема
Anonymous
 Python Tkinter: дождитесь ввода пользователя, прежде чем продолжить с MainLoop

Сообщение Anonymous »

Я использую Tkinter с Python 3.11 в Windows. < /p>
Следующая программа создает простое окно с меню. Пользователь нажимает на «Game -> Select Game Directory», после чего GAME_DIRECTORY_SELECTION () Функция призвана для пользователя выбрать каталог.

Код: Выделить всё

self.conf = Config(self.game_directory)
< /code>
, а затем конкретная конфигурация игрока читается здесь < /p>
self.player = Player(self.game_directory, self.player_id)
, потому что 'x' in utilx.dat был бы Player_id .
Однако, если каталог содержит несколько файлов игрока (скажем, util1.dat util3.dat и util7.dat , the Self.display Function_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_FILE_DSILE_DSILE_DAT и util7.dat ). Чтобы позволить игроку выбрать один. Это делается путем повторного использования окна для создания нового кадра, метки, списков с файлами игрока и кнопкой. Как только пользователь выбрал один файл игрока, этот кадр уничтожен, и файл конкретного игрока можно прочитать. < /P>

Код: Выделить всё

import tkinter as tk
from tkinter import Menu, Text, Label, Button, Listbox, StringVar, ttk
from tkinter import filedialog, messagebox
from tkinter import ttk
import os.path
import sys
import time
from pathlib import Path

#from inventory_view import InventoryViewer
from player import Player
from config import Config

class Game:
def __init__(self, root):
self.game_directory = None
self.filelist = None
self._selected_indices = ''
self.playerfile = None
self.conf = None

self.root = root
self.root.title("My Game Client")

self.create_main_window()

print('playerfile', self.playerfile) # (**)

def create_main_window(self):
# Create menu
self.menu = Menu(self.root)
self.root.config(menu=self.menu)

# Game menu
self.game_menu = Menu(self.menu, tearoff=0)
self.menu.add_cascade(label="Game", menu=self.game_menu)
self.game_menu.add_command(label="Select game directory", command=self.game_directory_selection)
self.game_menu.add_separator()
self.game_menu.add_command(label="Save game") # TO DO: add command
self.game_menu.add_command(label="Inventory viewer", command=self.inventory_view)
self.game_menu.add_command(label="Exit", command=self.root.quit)

def game_directory_selection(self):
""" Choose game directory, or quit."""

while True:
self.game_directory = tk.filedialog.askdirectory()
if not self.game_directory:
if tk.messagebox.askyesno(
icon='warning',
title="Game directory selection",
message="You haven't chosen a game directory.  Do you want to quit?"):
sys.exit(0)
else:
p = Path(self.game_directory)
self.filelist = list(p.glob('util[0-9].dat'))

if not self.filelist:
tk.messagebox.showerror(
title='Directory error',
message='Player files not found in directory')
else:
# If there is more than one player file,
# display a selection dialog to choose one.
if len(self.filelist) > 1:
filelist_tmp = [f.name for f in self.filelist]
self.display_file_selection(filelist_tmp)
else:
self.playerfile = self.filelist[0]
# Extract player ID from filename
self.player_id = self.playerfile.stem[-1]
print('self.player_id', self.player_id)
break

# Disable the menu entry for selecting game directory
self.game_menu.entryconfigure('Select game directory', state=tk.DISABLED)

# Read configuration files into self.conf variable
self.conf = Config(self.game_directory)

# Read player files into self.player variable
self.player = Player(self.game_directory, self.player_id) # (*)

def choose_file(self):
self._selected_indices = self._listbox.curselection()
self.playerfile = self.filelist[self._selected_indices[0]]

# Extract player ID from filename
self.player_id = self.playerfile.stem[-1]
print('self.player_id in choose_file', self.player_id)
self.gameselectionframe.destroy()

def display_file_selection(self, filelist):

# Destroy the previous frame if it exists
# try:
#     _gameselectionframe = self.root.nametowidget('gameselectionframe')
#     if _gameselectionframe:
#         _gameselectionframe.destroy()
# except KeyError:
#     pass

self.gameselectionframe = ttk.Frame(self.root, padding=(2, 2, 2, 2), name='gameselectionframe')
self.gameselectionframe.pack()

display_label = ttk.Label(self.gameselectionframe, text="Several player files were found. Please choose one.", width=60)
display_label.pack()

pl = tk.StringVar(value=filelist)
self._listbox = tk.Listbox(self.gameselectionframe, listvariable=pl, height=6, width=20)
self._listbox.selection_set(0)
self._listbox.pack()

btn = ttk.Button(self.gameselectionframe, text='Select', command=self.choose_file)
btn.pack()

def inventory_view(self):
if self.playerfile:
self.player = Player(self.game_directory)
#self.viewer = InventoryView(self.player.planets, self.conf)

else:
tk.messagebox.showerror(
title='Player file error',
message='No player file selected. Please select a game directory first.')

if __name__ == "__main__":
root = tk.Tk()
game = Game(root)
root.mainloop()
< /code>
Проблема, которую я столкнулся, когда есть несколько файлов игроков (например, в примере с 3 -ю игровыми файлами), заключается в том, что < /p>
self.player = Player(self.game_directory, self.player_id) # (*)
< /code>
выполняется до того, как у пользователя будет возможность выбрать один файл игрока. Тогда self.player_id 
не является , а файл не может быть должным образом прочитал. В этом случае мне нужно предотвратить продолжение программы, пока я не установил Self.Player_ID правильно.
Я попытался создать game_directory_selection () Использовать tk.toplevel window с grab_set () , чтобы «Salt» программа/Loopure, пока пользователь выбирает, но но но ищет. /> Я также пытался использовать quit () в начале display_file_selection () выйти из основного цикла, а затем Mainloop () в конце Display_file_selection () для резюме основной цикл. Они просто читают эти файлы на словарях для последующего использования. Что меня не беспокоит, потому что я не хочу ничего там печатать, это просто, чтобы проиллюстрировать тот факт, что Mainloop не ждал самостоятельно. wait_variable () Но они говорят, что обычное приложение GUI обычно не работает таким образом. Я также прочитал этот вопрос.
Заранее.

Подробнее здесь: https://stackoverflow.com/questions/796 ... e-mainloop
Реклама
Ответить Пред. темаСлед. тема

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

  • Похожие темы
    Ответы
    Просмотры
    Последнее сообщение
  • Tkinter блокирует Python, когда загружается значок, а Tk.mainloop находится в потоке
    Anonymous » » в форуме Python
    0 Ответы
    6 Просмотры
    Последнее сообщение Anonymous
  • Tkinter mainloop () не ухожу после закрытия окна
    Anonymous » » в форуме Python
    0 Ответы
    4 Просмотры
    Последнее сообщение Anonymous
  • Графика черепахи Python, .mainloop()
    Anonymous » » в форуме Python
    0 Ответы
    12 Просмотры
    Последнее сообщение Anonymous
  • RuntimeWarning: сопрограмма «отправка» никогда не ожидалась self.tk.mainloop(n) RuntimeWarning: включите трассировку, чт
    Anonymous » » в форуме Python
    0 Ответы
    54 Просмотры
    Последнее сообщение Anonymous
  • Почему mainloop() не в начале вашего кода, а в конце?
    Anonymous » » в форуме Python
    0 Ответы
    54 Просмотры
    Последнее сообщение Anonymous

Вернуться в «Python»