Я пытаюсь открыть окно tkinter одновременно с окном pygame, и я просмотрел все и нашел этот код, который я обрезал, чтобы это был минимально жизнеспособный продукт с наименьшим возможным количеством кода, как вставка весь код здесь будет включать множество различных инкапсулированных методов и классов, и это показывает основную идею моего кода. Я хочу, чтобы окно tkinter открывалось при нажатии кнопки pygame на главном экране pygame, и я успешно настроил класс, который позволяет мне создавать окна, нажав на указанную кнопку pygame. Иногда это не работает, но когда я не часто двигаю мышью, это работает. Это мое лучшее объяснение происходящего, поскольку я понятия не имею, что еще может быть причиной проблемы. Если бы проблема заключалась в том, что он никогда не работал, я бы отказался от этого подхода, но он работает, когда движения мыши медленные и роботизированные. Я открыт для всех предложений, потому что я в тупике.
Код: Выделить всё
import pygame as pg
import tkinter as tk
import os
from tkinter import ttk
# imports
# pg setup
pg.init()
screen = pg.display.set_mode((400,400))
screen.fill("black", pg.Rect((0,0), (400,400)))
# the encapsulated tkinter class
class FriendDialogue(tk.Tk):
def __init__(self, title):
self.root = super().__init__()
self._title = title
self.geometry("450x150")
self.title(self._title)
friend_dialogue.protocol("WM_DELETE_WINDOW", self.del_friend_window) # set
# the function to override the [x] button on tkinter window so that
# the window doesn't open multiple times
self.iconify()
def del_friend_window():
self.destroy()
self.root = None
friend_dialogue = FriendDialogue("Phone a friend") # create new tkinter window
# to make it so the button (screen) only works once
notRun = True
# main loop
while True:
for event in pg.event.get(): # event loop
if event.type == pg.QUIT: # [x] button on pg window
exit()
if event.type == pg.MOUSEBUTTONDOWN and notRun: # if click on screen
notRun = False # to run once
friend_dialogue.deiconify()
pg.display.update() # update pygame window
if friend_dialogue.root: # if not clicked yet, this won't run
friend_dialogue.update()
Currently with the above code, the window will always open but sometimes, it will immediately close with other times it staying open and being manipulable. When this happens the pygame window stops running and the tkinter window is manipulable, this is my desired behavior.
The issue is that other times, with the same code, the tkinter window will open and then, after a few seconds of neither window responding, both windows will crash. I believe that sometimes the mainloop will overtake the main thread where as other times the mainloop fails to start, messing with the pygame while loop updating, crashing both windows.
The reason I think this is since the print("init"*50) is never run, in the intended and in the buggy behavior except for when the behavior works as intended and then the tkinter window is closed with the [x] button.
So, where I am successful is in allowing for these two types of windows to be open at the same time and where I am unsuccessful is in allowing this behavior to happen consistently. I appreciate any help whatsoever, thanks for taking the time to read this question.
EDIT 2:
I have narrowed down the problem to running the update() or mainloop() methods of the tkinter window, though I still have no idea as to why these methods fail to work for me. When these methods are run, the entire program crashes with no error code. Any code before these methods is run will work fine, but nothing after will run. The only reason I can think of why these methods wouldn't work is if something that is required to be defined for these methods isn't but:
- No error code indicating this is raised, and
- These methods only presumably require the window to be defined which it is.
Following trying the approach posted in the comments involving using iconify() and deiconify(), I have found that it works fine save for the fact that it can be opened at any time. If there is anyway to not allow for a tkinter window to be opened while it is an icon, or withdrawn or 'iconified', it may solve my problem.
Источник: https://stackoverflow.com/questions/781 ... ify-is-run