尝试使用 pygamewidgets 按钮执行 openfilename(tkinter)

问题描述 投票:0回答:1

我试图制作一个瓦片地图制作器,在尝试获取 png 文件(瓦片表)时偶然发现了一个问题,askopenfile 函数崩溃了,这是按钮代码

self.tilemap_file_button = Button(self.Display,
                                      self.display_size[0]-100,
                                      10,
                                      32,
                                      32,
                                      image=self.tilemap_file_sprite,
                                      onClick=lambda:self.tile_map_button_pressed())

tile_map_button_pressed 函数

    def tile_map_button_pressed(self):
        tilesheet = filedialog.askopenfile()

整个事情

import sys

import pygame as py
import pygame_widgets
from pygame_widgets.button import Button
import tkinter
from tkinter import  filedialog

root = tkinter.Tk()
root.withdraw()
root.call('wm', 'attributes', '.', '-topmost', True)

#from tkinter.filedialog import askopenfilename
class app:
    def __init__(self)->None:
        py.init()


        self.clock = py.time.Clock()
        self.WINDOW_HIEGHT,self.WINDOW_WIDTH = 800,800
        self.Display = py.display.set_mode((self.WINDOW_WIDTH,self.WINDOW_HIEGHT),py.RESIZABLE)
        self.display_size = self.Display.get_size()
        self.RUNNING = True
        self.window_scale = 1
        self.tile_size = 32
        self.Tile_rect = [self.tile_size,self.tile_size]
        self.posX,self.posY = 0,0
        #start mouse at middle so at (0,0) it doesen't go top left
        self.mouse_pos = (self.WINDOW_WIDTH/2,self.WINDOW_HIEGHT/2)
        self.font = py.font.Font(None, 36)
        self.cord_text = self.font.render(f'pos: {self.posX},{self.posY}', True, (255, 255, 255))
        self.grid = self.Tile_map_grid(self.Tile_rect,self.Display)
        self.grid_posX,self.grid_posY=0,0
        self.show_sprite = py.image.load("show_sprite.png")
        self.tilemap_file_sprite = py.image.load("tile_map.png")
        self.show_background = True
        self.mouse_pressed = False
        self.handling_events = False
        self.MOUSE_MOTION_ALLOWED = True
        self.grabbed = False
        self.show_grid = True
        self.initialize_tilesheet=False
        self.background_height = 50
        self.a = 0
        self.show_button = Button(self.Display,
                                      self.display_size[0]-50,
                                      10,
                                      32,
                                      32,
                                      image=self.show_sprite,
                                      onClick= lambda :self.show_button_pressed()
                                      )
        self.tilemap_file_button = Button(self.Display,
                                      self.display_size[0]-100,
                                      10,
                                      32,
                                      32,
                                      image=self.tilemap_file_sprite,
                                      onClick=lambda:self.tile_map_button_pressed())



    def main_loop(self,FPS):
        LastFrameTick = 0
        while self.RUNNING:
            print('is running')
            tick = py.time.get_ticks()

            self.delta = (tick-LastFrameTick)/1000.0
            #if its outside of window dont change mouse position
            self.update_mouse_pos()
            updated_position =self.update_position(self.mouse_pos, self.Display, 100)
            self.posX += updated_position[0]
            self.posY += updated_position[1]
            self.update_grid_pos()
            self.Display.fill((70,70,70))
            if (not self.grabbed) and self.show_grid:
                self.Display.blit(self.grid,(-self.tile_size*self.window_scale
                            -self.posX+self.grid_posX,-self.tile_size*self.window_scale-self.posY+self.grid_posY))

            middle_point = py.draw.circle(self.Display,(0,0,0),(0-self.posX,0-self.posY),5*self.window_scale,20)

            if self.show_background:
                self.background()

            if self.initialize_tilesheet:

                filedialog.askopenfilename()
                self.initialize_tilesheet=False

            self.handling_events = self.handle_event()
            py.display.update()
            self.clock.tick(FPS)

            LastFrameTick = tick
    def handle_event(self):
        keys = py.key.get_pressed()

        events = py.event.get()
        for event in events:
            if event.type == py.MOUSEBUTTONDOWN or self.mouse_pressed:

                self.mouse_pressed = True
            if event.type == py.MOUSEBUTTONUP:
                self.mouse_pressed = False

            if self.mouse_pressed and event.type ==py.MOUSEMOTION:
                self.grabbed = True
            else:
                self.grabbed = False


            if event.type == py.KEYUP:

                if keys[py.K_g]:
                    self.show_grid = not self.show_grid
                if keys[py.K_s]:
                    self.show_background = not self.show_background
                    filedialog.askopenfilename()
                if keys[py.K_EQUALS]:
                    self.ZoomIn()
                elif keys[py.K_MINUS] :

                    self.ZoomOut()


            if event.type == py.VIDEORESIZE:
                self.display_size = self.Display.get_size()
                self.grid = self.Tile_map_grid(py.Vector2(self.tile_size*self.window_scale),self.Display)
                self.show_button._x = self.display_size[0]-50
                self.tilemap_file_button._x = self.display_size[0]-100
            if event.type == py.QUIT:
                self.exit()

        pygame_widgets.update(events)


    def exit(self):
        py.quit()
        sys.exit()
    def update_mouse_pos(self):
        if py.mouse.get_focused() and self.MOUSE_MOTION_ALLOWED:
            self.mouse_pos = py.mouse.get_pos()
        if py.mouse.get_focused() and not self.MOUSE_MOTION_ALLOWED:
            py.mouse.set_pos(self.mouse_pos)

    def Cords(self):
        self.cord_text = self.font.render(f'pos: {int(self.posX)},{int(self.posY)}', True, (255, 255, 255))
        self.Display.blit(self.cord_text, (10, 10))

    def Tile_map_grid(self,Tile_rect,Display)->py.Surface:
        window_size = Display.get_size()
        grid_size = window_size+py.Vector2(Tile_rect[0]*2)
        grid = py.surface.Surface(grid_size)
        grid.fill((70, 70, 70))
        for row in range(int((window_size[1]+Tile_rect[1]*4)/Tile_rect[0])):
            for tile in range(int((window_size[0]+Tile_rect[0]*4)/Tile_rect[1])):

                py.draw.rect(grid, (255, 255, 255), [tile*Tile_rect[0], row*Tile_rect[1], Tile_rect[0], Tile_rect[1]], 1)
        return grid


    def update_position(self,mousep,window,Speed)->None:

        Speed = int(Speed * self.display_size[0] /1000 * self.window_scale)
        self.mouse_rel = py.mouse.get_rel() * Speed


        if self.grabbed:


            return (-self.mouse_rel[0]*self.delta*100,-self.mouse_rel[1]*self.delta*100)

        window_size = window.get_size()
        corner_width = 160
        edge_width = 70
        corners = {
            'top_left':(corner_width,0,
                        corner_width+self.background_height,self.background_height,
                        -Speed*self.delta,-Speed*self.delta)

            ,'down_right':(window_size[0],window_size[0]-corner_width
                           ,window_size[1],window_size[1]-corner_width,
                           Speed*self.delta,Speed*self.delta),

            'top_right':(window_size[0],window_size[0]-corner_width
                         ,corner_width+self.background_height,self.background_height,
                         +Speed*self.delta,-Speed*self.delta)

            ,'down_left':(corner_width,0,window_size[1],window_size[1]-corner_width,-Speed*self.delta,Speed*self.delta)
        }
        edges = {
                 'top':(edge_width+50,50,0,-Speed*1.4*self.delta,1)
                ,'bottom':(window_size[1],window_size[1]-edge_width,0,+Speed*1.4*self.delta,1),
                 'left':(edge_width,-edge_width,-Speed*1.4*self.delta,0,0)
                ,'right':(window_size[0],window_size[-0]-edge_width,Speed*1.4*self.delta,0,0)}

        for corner in corners:
            if (mousep[0]<corners[corner][0] and mousep[0]>corners[corner][1]
                    and mousep[1]<corners[corner][2] and mousep[1]>corners[corner][3]) :
                return (corners[corner][4],corners[corner][5])

        for edge in edges:
            if mousep[1] < self.background_height:
                continue
            if mousep[edges[edge][4] ] < edges[edge][0] and mousep[edges[edge][4] ] > edges[edge][1]:
                return (edges[edge][2],edges[edge][3])
        return (0,0)

    def ZoomIn(self)->None:
        if self.window_scale > 1.9:return
        self.window_scale+=0.1
        self.grid = self.Tile_map_grid(py.Vector2(self.tile_size*self.window_scale),self.Display)

    def ZoomOut(self)->None:
        if self.window_scale < 0.7: return
        self.window_scale -= 0.1
        self.grid = self.Tile_map_grid(py.Vector2(self.tile_size * self.window_scale), self.Display)
        file_path = filedialog.askopenfilename()

    def update_grid_pos(self):

        self.grid_posX = int(self.posX/(self.tile_size*self.window_scale))*self.tile_size*self.window_scale
        self.grid_posY = int(self.posY /(self.tile_size*self.window_scale))*self.tile_size * self.window_scale

    def show_button_pressed(self):
        self.show_background = not self.show_background

    def background(self):
        top_background = py.draw.rect(self.Display, (45, 45, 45), [0, 0, self.display_size[0], self.background_height])
        self.Cords()

    def tile_map_button_pressed(self):
        tilesheet = filedialog.askopenfile()



if __name__ == "__main__":
    new_app = app()
    new_app.main_loop(60)

我尝试在 (tile_map_button_pressed) 时将变量更改为 true 执行,然后在主循环中运行askopenfile(当它为真时),但这没有起作用

这是一个较小的问题示例,单击按钮会使askopenfile崩溃



import pygame
import pygame_widgets
from pygame_widgets.button import Button
import tkinter
from tkinter import  filedialog

pygame.init()
win = pygame.display.set_mode((600, 600))


def button_clicked():
    filedialog.askopenfilename()

button = Button(
    win,
    150,
    150,
    300,
    150,
    text='button',
    fontSize=50,
    margin=20,
    inactiveColour=(150, 150, 150),
    hoverColour=(170, 170, 170),
    pressedColour=(200, 200, 200),
    radius=20,
    onClick=lambda: button_clicked()
)

run = True
while run:
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            pygame.quit()
            run = False
            quit()

    win.fill((255, 255, 255))

    pygame_widgets.update(events)  
    pygame.display.update()
python tkinter pygame
1个回答
0
投票

我不知道它为什么起作用,但使用 onRelease 可以修复它

import pygame
import pygame_widgets
from pygame_widgets.button import Button
import tkinter
from tkinter import  filedialog

pygame.init()
win = pygame.display.set_mode((600, 600))


def button_clicked():
    """Create a Tk file dialog and cleanup when finished"""
    top = tkinter.Tk()
    top.withdraw()  # hide window
    file_name = tkinter.filedialog.askopenfilename(parent=top)
    top.destroy()
    return file_name
a = lambda :True
button = Button(
    win,
    150,
    150,
    300,
    150,
    text='button',
    fontSize=50,
    margin=20,
    inactiveColour=(150, 150, 150),
    hoverColour=(170, 170, 170),
    pressedColour=(200, 200, 200),
    radius=20,
    onRelease=button_clicked
)
run=True
while run:
    events = pygame.event.get()
    for event in events:
        if event.type == pygame.QUIT:
            pygame.quit()
            run = False
            quit()

    win.fill((255, 255, 255))

    pygame_widgets.update(events)
    pygame.display.update()

© www.soinside.com 2019 - 2024. All rights reserved.