Python tkinter 减少了路径但作为完整目录打开 [英] Python tkinter cut down path but open as full directory

查看:22
本文介绍了Python tkinter 减少了路径但作为完整目录打开的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我的完整 Python 代码:

from tkinter import *导入全局导入操作系统从 PIL 导入 Image、ImageTk、ImageGrab将 tkinter 作为 tk 导入导入pyautogui导入日期时间#date &时间现在 = datetime.datetime.now()根 = tk.Tk()root.title("注销")root.minsize(840, 800)# 添加网格大型机 = tk.Frame(root)mainframe.columnconfigure(0, weight=1)mainframe.rowconfigure(0, weight=1)mainframe.pack(pady=100, padx=100)# 创建一个 Tkinter 变量tkvar = tk.StringVar(root)# 目录directory = "C:/Users/eduards/Desktop/work/data/to-do"选择 = glob.glob(os.path.join(directory, "*.jpg"))tkvar.set('...To Sign Off...') # 设置默认选项# 下拉式菜单popupMenu = tk.OptionMenu(mainframe, tkvar, *choices)tk.Label(mainframe, text="Choose your sign off here:").grid(row=1, column=1)popupMenu.grid(row=2, column=1)label2 = tk.Label(大型机,图像=无)label2.grid(row = 4, column = 1, rowspan = 10)# 更改下拉回调.def change_dropdown(*args):"""更新 label2 图像."""imgpath = tkvar.get()img = Image.open(imgpath)img = img.resize((240,250))照片 = ImageTk.PhotoImage(img)label2.image = 照片label2.configure(图像=照片)tk.Button(mainframe, text="Open", command=change_dropdown).grid(row=3, column=1)def var_states():text_file = open("logfile.txt", "a")text_file.write("TIME: %s, USER: %s, 一个 %d, 两个 %d\n" % (now,os.getlogin(), var1.get(), var2.get()))text_file.close()打印(一个 %d,两个 %d" % (var1.get(), var2.get()))var1 = IntVar()Checkbutton(mainframe, text="Ingredients present in full (任何过敏原以粗体显示,如有必要,过敏原警告)", variable=var1).grid(column = 2, row=1, sticky=W)var2 = IntVar()Checkbutton(mainframe, text="May Contain Statement.", variable=var2).grid(column = 2, row=2, sticky=W)var3 = IntVar()Checkbutton(mainframe, text="Cocoa Content (%).", variable=var3).grid(column = 2, row=3,sticky=W)var4 = IntVar()Checkbutton(mainframe, text="除可可脂之外的植物脂肪", variable=var4).grid(column = 2, row=4, sticky=W)var5 = IntVar()Checkbutton(mainframe, text="Instructions for Use.", variable=var5).grid(column = 2, row=5, sticky=W)var6 = IntVar()Checkbutton(mainframe, text="Additional warning statements (pitt/stone, hyperactivity etc)", variable=var6).grid(column = 2, row=6, sticky=W)var7 = IntVar()Checkbutton(mainframe, text="营养信息可见", variable=var7).grid(column = 2, row=7, sticky=W)var8 = IntVar()Checkbutton(mainframe, text="Storage conditions", variable=var8).grid(column = 2, row=8, sticky=W)var9 = IntVar()Checkbutton(mainframe, text="Best Before & Batch Information", variable=var9).grid(column = 2, row=9, sticky=W)var10 = IntVar()Checkbutton(mainframe, text="Net Weight & Correct Font Size.", variable=var10).grid(column = 2, row=10, sticky=W)var11 = IntVar()Checkbutton(mainframe, text="Barcode - Inner", variable=var11).grid(column = 2, row=11, sticky=W)var12 = IntVar()Checkbutton(mainframe, text="地址和联系方式正确", variable=var12).grid(column = 2, row=12, sticky=W)定义用户():用户输入 = os.getlogin()tk.Label(mainframe, text = user_input, font='Helvetica 18 bold').grid(row = 0, column = 1)用户()定义保存():# pyautogui.press('alt')# pyautogui.press('printscreen')# img = ImageGrab.grabclipboard()# img.save('paste.jpg', 'JPEG')var_states()tk.Button(mainframe, text = "Save", command = save).grid(row = 20, column = 1)root.mainloop()

当我运行代码时,会有一个 jpg 文件的下拉列表.目前它显示完整的目录,如下所示:

我之前已经创建了一篇关于如何修剪路径的帖子,并得到了如下内容:

files = os.listdir("C:/Users/eduards/Desktop/work/data/to-do")打印(文件)

但是如果我使用上面的代码,当点击open时它不会打开路径,因为它没有完整的路径名.

我想要做的是,为了显示目的而减少路径名,然后按照原始完整路径打开图像.

举个例子:

当前下拉菜单显示C:/Users/eduards/Desktop/work/data/to-do/img1.jpg我想要的结果是 img1.jpg 但在后台打开上面的整个路径.

<块引用>

复制评论:这是我试过的

directory = os.path.splitdrive("C:/Users/eduards/Desktop/work/data/to-do")选择 = glob.glob(os.path.join(directory[1:], "*.jpg"))

,但是说

 预期的 str、bytes 或 os.Pathlike,而不是元组.

已添加 [1:] 因为路径被拆分为 2 并返回其中的第二部分.

解决方案

问题:在OptionMenu中只显示文件名,但从选择中获取原始完整路径.

创建您自己的OptionMenu,它在dict 中保存所有图像的完整路径,并仅显示文件名作为选项.

<小时>

  1. 通过继承(tk.OptionMenu)定义你自己的小部件FileNameOptionMenu

    class FileNameOptionMenu(tk.OptionMenu):def __init__(self, parent, directory, extension, callback):

  2. 从所有图像中获取完整路径并提取文件名.
    使用 filename 作为 key 并将完整路径作为 value 保存在 dict 中的每个完整路径.

     # 将 `glob` 的结果保存在 `dict` 中self.glob = {}对于 glob.glob(os.path.join(directory, "*.{}".format(extension))) 中的 fpath:文件名,扩展名 = os.path.splitext(os.path.split(fpath)[1])self.glob[文件名] = fpath

  3. 定义一个变量来保存选定的选项以供以后使用.
    使用 dict 中的 keyslist 初始化继承的 tk.OptionMenu.
    class 方法 self.command 作为 command= 传递.
    保存回调以备后用.

     self.selected = tk.StringVar(parent, '选择图片...')super().__init__(parent, self.selected, *list(self.glob),命令=自我.命令)self.callback = 回调

  4. 这个类方法在每次点击选项选择时都会被调用.在调用时,它使用所选选项的完整路径调用 self.callback,即 ImageLabel.configure.

     def 命令(self, val):self.callback(image=self.glob.get(self.selected.get()))

  5. 通过继承 (tk.Label) 定义您自己的小部件 ImageLabel.
    这个类扩展了 tk.Label.configure 来处理 .configure(image= 而不是 .configure(image=.

    class ImageLabel(tk.Label):def __init__(self, parent):super().__init__(parent, image=None)

  6. 重载继承的类方法tk.Label.configure.
    捕获名称参数 image= 并将传递的完整路径替换为 image 对象.

     def configure(self, **kwargs):键 = '图像'如果输入 kwargs:# 用图片替换文件路径fpath = kwargs[key]img = Image.open(fpath)img = img.resize((240, 250))self._image = ImageTk.PhotoImage(img)kwargs[key] = self._image

  7. 调用原来的tk.Label.configure来显示图片

     super().configure(**kwargs)

<块引用>

用法:

导入 tkinter 作为 tk从 PIL 导入 Image、ImageTk导入全局,操作系统类应用程序(tk.Tk):def __init__(self):super().__init__()self.label_image = ImageLabel(parent=self)self.label_image.grid(row=2, column=0)self.option_menu = \FileNameOptionMenu(parent=self,directory='C:/Users/eduards/Desktop/work/data/to-do',扩展='jpg',回调=self.label_image.configure)self.option_menu.grid(row=0, column=0)如果 __name__ == "__main__":应用程序().主循环()

使用 Python 测试:3.5

Here is my full Python code:

from tkinter import *
import glob
import os
from PIL import Image, ImageTk, ImageGrab
import tkinter as tk
import pyautogui
import datetime

#date & time
now = datetime.datetime.now()

root = tk.Tk()
root.title("SIGN OFF")
root.minsize(840, 800)

# Add a grid
mainframe = tk.Frame(root)
mainframe.columnconfigure(0, weight=1)
mainframe.rowconfigure(0, weight=1)
mainframe.pack(pady=100, padx=100)

# Create a Tkinter variable
tkvar = tk.StringVar(root)


# Directory
directory = "C:/Users/eduards/Desktop/work/data/to-do"
choices = glob.glob(os.path.join(directory, "*.jpg"))
tkvar.set('...To Sign Off...') # set the default option

# Dropdown menu
popupMenu = tk.OptionMenu(mainframe, tkvar, *choices)
tk.Label(mainframe, text="Choose your sign off here:").grid(row=1, column=1)
popupMenu.grid(row=2, column=1)

label2 = tk.Label(mainframe, image=None)
label2.grid(row = 4, column = 1, rowspan = 10)

# On change dropdown callback.
def change_dropdown(*args):
    """ Updates label2 image. """
    imgpath = tkvar.get()
    img = Image.open(imgpath)
    img = img.resize((240,250))
    photo = ImageTk.PhotoImage(img)
    label2.image = photo
    label2.configure(image=photo)


tk.Button(mainframe, text="Open", command=change_dropdown).grid(row=3, column=1)


def var_states():
    text_file = open("logfile.txt", "a")
    text_file.write("TIME: %s, USER: %s, One %d, Two %d\n" % (now,os.getlogin(), var1.get(), var2.get()))
    text_file.close()
    print("One %d, Two %d" % (var1.get(), var2.get()))

var1 = IntVar()
Checkbutton(mainframe, text="Ingredients present in full (any allergens in bold with allergen warning if necessary)", variable=var1).grid(column = 2, row=1, sticky=W)
var2 = IntVar()
Checkbutton(mainframe, text="May Contain Statement.", variable=var2).grid(column = 2, row=2, sticky=W)
var3 = IntVar()
Checkbutton(mainframe, text="Cocoa Content (%).", variable=var3).grid(column = 2, row=3, sticky=W)
var4 = IntVar()
Checkbutton(mainframe, text="Vegetable fat in addition to Cocoa butter", variable=var4).grid(column = 2, row=4, sticky=W)
var5 = IntVar()
Checkbutton(mainframe, text="Instructions for Use.", variable=var5).grid(column = 2, row=5, sticky=W)
var6 = IntVar()
Checkbutton(mainframe, text="Additional warning statements (pitt/stone, hyperactivity etc)", variable=var6).grid(column = 2, row=6, sticky=W)
var7 = IntVar()
Checkbutton(mainframe, text="Nutritional Information Visible", variable=var7).grid(column = 2, row=7, sticky=W)
var8 = IntVar()
Checkbutton(mainframe, text="Storage Conditions", variable=var8).grid(column = 2, row=8, sticky=W)
var9 = IntVar()
Checkbutton(mainframe, text="Best Before & Batch Information", variable=var9).grid(column = 2, row=9, sticky=W)
var10 = IntVar()
Checkbutton(mainframe, text="Net Weight & Correct Font Size.", variable=var10).grid(column = 2, row=10, sticky=W)
var11 = IntVar()
Checkbutton(mainframe, text="Barcode - Inner", variable=var11).grid(column = 2, row=11, sticky=W)
var12 = IntVar()
Checkbutton(mainframe, text="Address & contact details correct", variable=var12).grid(column = 2, row=12, sticky=W)

def user():
    user_input = os.getlogin()
    tk.Label(mainframe, text = user_input, font='Helvetica 18 bold').grid(row = 0, column = 1)


user()


def save():
    # pyautogui.press('alt')
    # pyautogui.press('printscreen')
    # img = ImageGrab.grabclipboard()
    # img.save('paste.jpg', 'JPEG')

    var_states()


tk.Button(mainframe, text = "Save", command = save).grid(row = 20, column = 1)


root.mainloop()

When I run the code, there will be a dropdown of jpg files. Currently It shows the full directory like so:

I have created a post earlier on how to trim down the path and got something like this:

files = os.listdir("C:/Users/eduards/Desktop/work/data/to-do")
print(files)

But If I use that code above, it will not open the path when clicked open because it doesn't have the full path name.

What I am trying to do is, cut down the path name for display purposes and open the image by following the original full path.

As an example:

The current drop-down menu shows C:/Users/eduards/Desktop/work/data/to-do/img1.jpg My desired result is img1.jpg but in the background open the whole path of above.

Copy comment: this is what I have tried

directory = os.path.splitdrive("C:/Users/eduards/Desktop/work/data/to-do")
choices = glob.glob(os.path.join(directory[1:], "*.jpg"))

, but says

expected str, bytes or os.Pathlike, not tuple. 

Have added [1:] because the path is split into 2 and returning the 2nd part of it.

解决方案

Question: Show only the filename in OptionMenu but get original full path from selection.

Create your own OptionMenu which holds from all images the full path in a dict and shows only the filename as options.


  1. Define your own widget FileNameOptionMenu by inheriting from (tk.OptionMenu)

    class FileNameOptionMenu(tk.OptionMenu):
        def __init__(self, parent, directory, extension, callback):
    

  2. Get from all images the full path and extract the filename.
    Save every full path in a dict using the filename as key and the full path as value.

            # Save result from `glob` in a `dict`
            self.glob = {}
            for fpath in glob.glob(os.path.join(directory, "*.{}".format(extension))):
                filename, extension = os.path.splitext(os.path.split(fpath)[1])
                self.glob[filename] = fpath
    

  3. Define a variable which holds the selected option for later usage.
    Init the inherited tk.OptionMenu with the list of the keys from the dict.
    Pass the class method self.command as command=.
    Save the callback for later usage.

            self.selected = tk.StringVar(parent, 'Select a image...')
            super().__init__(parent, self.selected, *list(self.glob),
                             command=self.command)
    
            self.callback = callback
    
    

  4. This class method get called on every click option selection. On call, it calls the self.callback, which is ImageLabel.configure, with the full path of the selected option.

        def command(self, val):
            self.callback(image=self.glob.get(self.selected.get()))
    

  5. Define your own widget ImageLabel by inheriting from (tk.Label).
    This class extends the tk.Label.configure to handle .configure(image=<full path> instead of .configure(image=<image object>.

    class ImageLabel(tk.Label):
        def __init__(self, parent):
            super().__init__(parent, image=None)
    

  6. Overload the inherited class method tk.Label.configure.
    Catch the name argument image= and replace the passed full path with a image object.

        def configure(self, **kwargs):
            key = 'image'
            if key in kwargs:
                # Replace the filepath with the image
                fpath = kwargs[key]
    
                img = Image.open(fpath)
                img = img.resize((240, 250))
                self._image = ImageTk.PhotoImage(img)
    
                kwargs[key] = self._image
    

  7. Call the original tk.Label.configure to show the image

            super().configure(**kwargs)
    

Usage:

import tkinter as tk
from PIL import Image, ImageTk
import glob, os

class App(tk.Tk):
    def __init__(self):
        super().__init__()

        self.label_image = ImageLabel(parent=self)
        self.label_image.grid(row=2, column=0)

        self.option_menu = \
            FileNameOptionMenu(parent=self,
                               directory='C:/Users/eduards/Desktop/work/data/to-do',
                               extension='jpg',
                               callback=self.label_image.configure
                                               )
        self.option_menu.grid(row=0, column=0)


if __name__ == "__main__":
    App().mainloop()

Tested with Python: 3.5

这篇关于Python tkinter 减少了路径但作为完整目录打开的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆