第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問(wèn)題,去搜搜看,總會(huì)有你想問(wèn)的

在 Python Tkinter 中使用圖像的問(wèn)題

在 Python Tkinter 中使用圖像的問(wèn)題

交互式愛(ài)情 2023-12-20 14:06:18
我正在使用 Tkinter 創(chuàng)建 Blackjack GUI 游戲,但遇到了一個(gè)問(wèn)題:當(dāng)添加新牌時(shí),交易按鈕會(huì)從屏幕上清除舊牌的圖像。我有根據(jù)的猜測(cè)是,當(dāng)我再次使用該函數(shù)時(shí),card_image該函數(shù)的內(nèi)部deal()正在覆蓋自身。如果是這種情況,為什么會(huì)這樣?最好的解決辦法是什么?謝謝。import randomfrom tkinter import *from PIL import Image, ImageTkroot =Tk()root.title('21 Blackjack')root.iconbitmap('images/21_cards.ico')root.geometry('1280x750')root.configure(bg='green')cards = []suits = ['hearts', 'clubs', 'diamonds', 'spades']face_cards = ['ace', 'jack', 'queen', 'king']extension = 'png'for y in suits:    for x in range(2, 11):        name = 'images/{}-{}.{}'.format(str(x), y, extension)        cards.append(name)    for x in face_cards:        name = 'images/{}-{}.{}'.format(str(x), y, extension)        cards.append(name)print(cards)print(len(cards))random.shuffle(cards)print(cards[0])hand = []def deal():    global card_image, card_label, hand    card_image = ImageTk.PhotoImage(Image.open(cards[0]).resize((180, 245), Image.ANTIALIAS))    card_label = Label(root, image=card_image, relief="raised").pack(side="left")    hand += cards[:1]    cards.pop(0)    print(hand)deal_button = Button(root, text="deal", command=deal).pack()root.mainloop()
查看完整描述

3 回答

?
一只甜甜圈

TA貢獻(xiàn)1836條經(jīng)驗(yàn) 獲得超5個(gè)贊

正如人們指出的那樣,我需要添加card_label.image = card_image該函數(shù)并刪除card_image和card_label全局以阻止圖像被刪除。但出于某種原因,Python 不喜歡在我這樣做之前打包圖像。


該函數(shù)現(xiàn)在看起來(lái)像這樣。


    global hand

    card_image = ImageTk.PhotoImage(Image.open(cards[0]).resize((180, 245), Image.ANTIALIAS))

    card_label = Label(root, image=card_image, relief="raised")

    card_label.image = card_image

    card_label.pack(side="left")

    hand += cards[:1]

    cards.pop(0)

    print(hand)


查看完整回答
反對(duì) 回復(fù) 2023-12-20
?
尚方寶劍之說(shuō)

TA貢獻(xiàn)1788條經(jīng)驗(yàn) 獲得超4個(gè)贊

代替


card_image = ImageTk.PhotoImage(Image.open(cards[0]).resize((180, 245), Image.ANTIALIAS))

card_label = Label(root, image=card_image, relief="raised").pack(side="left")

做:


card_label = Label(root, image=card_image, relief="raised").pack(side="left")

card_image = ImageTk.PhotoImage(Image.open(cards[0]).resize((180, 245), Image.ANTIALIAS))

card_label.image = card_image #Keeps reference to the image so it's not garbage collected

請(qǐng)注意,當(dāng)您想使用照片時(shí),請(qǐng)使用變量card_image


查看完整回答
反對(duì) 回復(fù) 2023-12-20
?
滄海一幻覺(jué)

TA貢獻(xiàn)1824條經(jīng)驗(yàn) 獲得超5個(gè)贊

您應(yīng)該使用圖像池。你很幸運(yùn),我這里有一個(gè)


import os

from glob import glob

from PIL import Image, ImageTk

from typing import List, Tuple, Union, Dict, Type

from dataclasses import dataclass


@dataclass

class Image_dc:

    image  :Image.Image

    rotate :int                = 0

    photo  :ImageTk.PhotoImage = None

    

    def size(self) -> Tuple[int]:

        if not self.photo is None:

            return self.photo.width(), self.photo.height()

            

        return self.image.width, self.image.height



class ImagePool(object):

    ##__> PRIVATE INTERFACE <__##

    

    __PATHS  = dict()

    __IMAGES = dict()

    

    @staticmethod

    def __name(path) -> str:

        return os.path.basename(os.path.splitext(path)[0])

            

    @staticmethod

    def __unique(path:str, prefix:str='') -> str:

        name = f'{prefix}{ImagePool.__name(path)}'

        if name in ImagePool.names():

            sol = 'using a prefix' if not prefix else f'changing your prefix ({prefix})'

            msg = ("WARNING:\n"

                  f"{name} was not loaded due to a same-name conflict.\n"

                  f"You may want to consider {sol}.\n\n")

            print(msg)

                   

            return None

            

        return name

            

    @staticmethod

    def __request(name:str) -> Image_dc:

        if name in ImagePool.__PATHS:

            path = ImagePool.paths(name)

            if os.path.isfile(path):

                if name not in ImagePool.__IMAGES:   

                    ImagePool.__IMAGES[name] = Image_dc(Image.open(path))

                return ImagePool.__IMAGES[name]

            else:

                raise ValueError(f'ImagePool::__request - Path Error:\n\tpath is not a valid file\n\t{path}')

                

        raise NameError(f'ImagePool::__request - Name Error:\n\t"{name}" does not exist')

        return None

    

    @staticmethod

    def __size(iw:int, ih:int, w:int=None, h:int=None, scale:float=1.0) -> Tuple[int]:

        if not w is None and not h is None:

            if iw>ih:

                ih = ih*(w/iw)

                r = h/ih if (ih/h) > 1 else 1

                iw, ih = w*r, ih*r

            else:

                iw = iw*(h/ih)

                r = w/iw if (iw/w) > 1 else 1

                iw, ih = iw*r, h*r

                

        return int(iw*scale), int(ih*scale)

        

    ##__> PUBLIC INTERFACE <__##

    

    @staticmethod

    def names(prefix:str='') -> List[str]:

        names = [*ImagePool.__PATHS]

        return names if not prefix else list(filter(lambda name, pre=prefix: name.startswith(pre), names))

        

    @staticmethod

    def paths(name:str=None) -> Union[Dict, str]:

        if name is None:

            return ImagePool.__PATHS

            

        if name in ImagePool.__PATHS:

            return ImagePool.__PATHS[name]

            

        raise NameError(f'ImagePool::paths - Name Error:\n\tname "{name}" does not exist')

        

    @staticmethod

    def images(name:str=None, prefix:str='') -> Union[Dict, Image.Image]:

        if name is None:

            return {name:ImagePool.__request(name).image for name in self.names(prefix)}

            

        return ImagePool.__request(name).image

    

    @staticmethod

    def photos(name:str=None, prefix:str='') -> Union[Dict, ImageTk.PhotoImage]:

        if name is None:

            return {name:ImagePool.__request(name).photo for name in self.names(prefix)}

        

        return ImagePool.__request(name).photo

        

    @staticmethod

    def append_file(path:str, prefix:str='') -> Type:

        if not os.path.isfile(path):

            raise ValueError(f'ImagePool::append_file - Value Error:\n\tpath is not valid\n\t{path}')

            

        name = ImagePool.__unique(path, prefix)

        

        if name:

            ImagePool.__PATHS[name] = path

            

        return ImagePool

            

    @staticmethod

    def append_directory(directory:str, filters=['*.png', '*.jpg'], prefix:str='') -> Type:

        if not os.path.isdir(directory):

            raise ValueError(f'ImagePool::append_directory - Value Error:\n\tdirectory is not valid\n\t{directory}')

            

        filters = filters if isinstance(filters, (List, Tuple)) else [filters]

            

        for filter in filters:

            for path in glob(f'{directory}/{filter}'):

                ImagePool.append_file(path, prefix)

                

        return ImagePool

    

    @staticmethod

    def photo(name:str, width:int=None, height:int=None, scale:float=1.00, rotate:int=None) -> ImageTk.PhotoImage:

        image_t = ImagePool.__request(name)

        size    = ImagePool.__size(*image_t.size(), width, height, scale)

        rotate  = image_t.rotate if rotate is None else rotate

                    

        #only resize if the new size or rotation is different than the current photo size or rotation

        #however, a small margin for error must be considered for the size            

        diff = tuple(map(lambda i, j: i-j, image_t.size(), size)) 

        if (diff > (1, 1)) or (diff < (-1, -1)) or (image_t.rotate != rotate):

            image_t.rotate = rotate

            image_t.photo  = ImageTk.PhotoImage(image_t.image.resize(size, Image.LANCZOS).rotate(rotate))

              

        return image_t.photo

    

使用該文件您可以非常輕松地做很多事情。您可以將所有卡片圖像放入一個(gè)文件夾中,并通過(guò)以下方式獲取它們:


ImagePool.append_directory(path_to_folder)

然后,您可以獲取任何卡并強(qiáng)制其適合其父級(jí)(無(wú)論如何):


somelabel['image'] = ImagePool.photo(image_name, allotted_width, allotted_height)

要不就:


somelabel['image'] = ImagePool.photo(image_name)

你可以得到池中每個(gè)名字的列表


deck = ImagePool.names()

或者在附加目錄的同時(shí)抓取它


deck = ImagePool.append_directory(path_to_folder).names()

這對(duì)您非常有幫助,因?yàn)槟梢院?jiǎn)單地洗牌并彈出該列表作為游戲中的官方“牌組”。像這樣:


somecard['image'] = ImagePool.photo(deck.pop(0))

假設(shè)您不僅擁有卡片圖形,但又不想在創(chuàng)建牌組時(shí)獲得所有圖像,那么也有一個(gè)解決方案。


首先在附加卡片圖像目錄時(shí)提供前綴,然后在調(diào)用names(). 只要卡片圖像目錄中只有卡片圖像,則只會(huì)返回卡片名稱。


deck = ImagePool.append_directory(path_to_folder, prefix='cards_').names('cards_')

筆記:


allotted區(qū)域僅被分配,絕不應(yīng)被假定為代表實(shí)際圖像的最終寬度和/或高度。圖像將盡一切努力適應(yīng)分配的空間,而不會(huì)丟失其原始的高度和寬度比例。如果您不提供分配的寬度和高度,圖像將是完整尺寸。


所有圖像和照片參考都會(huì)自動(dòng)維護(hù)在ImagePool. 沒(méi)有理由存儲(chǔ)您自己的參考資料


整個(gè)類是靜態(tài)的,因此可以在任何地方訪問(wèn)所有圖像和照片的引用,而無(wú)需ImagePool實(shí)例。換句話說(shuō),您永遠(yuǎn)不需要這樣做:images = ImagePool()因此永遠(yuǎn)不需要弄清楚如何進(jìn)入images某些class或其他文檔。


在您開(kāi)始請(qǐng)求圖像之前,不會(huì)實(shí)際加載圖像,然后它會(huì)自動(dòng)發(fā)生。這是一件好事。你有 52 張卡,但如果你在第一場(chǎng)比賽中只使用 ex: 6 ~ 只有 6 張會(huì)完全加載。最終,所有卡牌都會(huì)被玩完并被完全加載,并且您在游戲中不會(huì)出現(xiàn)嘗試一次完全創(chuàng)建 52 張卡牌的情況。


該類ImagePool具有更多功能,但此處解釋的功能是您的游戲所需的全部功能。


查看完整回答
反對(duì) 回復(fù) 2023-12-20
  • 3 回答
  • 0 關(guān)注
  • 260 瀏覽
慕課專欄
更多

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購(gòu)課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)