1

我有一堆链接和标签list来查看我想要制作具有下一个上一个功能的图像查看器的那些。我的各个图像的链接和标签位于list. 到目前为止,我已经尝试过:

urls=[url,url1,url2,url3]
labels=["label 1","label 2","label 3","label 4"]

images=[]
for ur in urls:
    raw_data = urllib.request.urlopen(ur).read()
    im = Image.open(io.BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    images.append(image)

现在我已经准备好图像images,现在我想在图像查看器中显示它,但在图像查看器中只有最后一张图像可见。

Label(root).grid(row=1,column=1)

for i in range(len(images)):
    image_label=Label(root,image=images[i])
    image_label.grid(row=1,column=2)
    
    name=Label(root,text=labels[i])
    name.grid(row=2,column=2)

def left():
    image_label=Label(root,image=images[i-1])
    image_label.grid(row=1,column=2)

def right():
    image_label=Label(root,image=images[i+1])
    image_label.grid(row=1,column=2)
    
left_button=Button(root,text="Left",command=left)
left_button.grid(row=2,column=1)

right_button=Button(root,text="Right",command=right)
right_button.grid(row=2,column=3)

右键不工作,左键工作,但只有一次。当我第二次单击左键时,没有任何效果。
单击右键时出错:

line 45, in right
    image_label=Label(root,image=images[i+1])
IndexError: list index out of range
4

4 回答 4

1

该代码非常接近原始发布的示例。

没有lambdain Button,只是直接command可以访问左右功能。

名称标签是不必要的,因为label对象已经具有text属性,因此我将图像和文本集成为单个label并增加了字体大小。

label复合用于控制图像相对于文本的显示位置,我选择了top. 也就是说,图像将放置在文本上方。

使用globalin 函数跟踪count


from tkinter import Tk, Label, Frame, Button
from PIL import ImageTk, Image
import io
import requests
import urllib 

root = Tk()
urls = [url, url1, url2, url3]
labels = ["label 1","label 2","label 3","label 4"]
count = -1
images = []
for ur in urls:
    raw_data = urllib.request.urlopen( ur ).read()
    im = Image.open(io.BytesIO( raw_data ))
    image = ImageTk.PhotoImage(im)
    images.append(image)

def left( ):
    global count
    count = (count - 1) % len(images)
    image_label.config(image = images[count], text = labels[count])

def right( ):
    global count
    count = (count + 1) % len(images)
    image_label.config(image = images[count], text = labels[count])

image_label = Label(
    root, image = images[count], font = "Helvetica 20 normal",
    text = labels[count], compound = "top")
image_label.grid(row = 0, column = 0, columnspan = 2, sticky = "nsew")

Button(
    root, text = "<< LEFT", command = left).grid( row = 1, column = 0, sticky = "ew")
Button(
    root, text = "RIGHT >>", command = right).grid(row = 1, column = 1, sticky = "ew")

right( ) # display first image
root.mainloop()
于 2021-08-08T09:07:25.020 回答
1

Here's a way to do it by showing and hiding pairs of Labels with the image and it name on them. For development and testing purposes, it loads the images from disk instead of downloading them, but you can easily replace that with what you have in your question.

from pathlib import Path
from PIL import Image, ImageTk
from tkinter import Button, Tk, Label


root = Tk()
root.title('Image Viewer')

# Create thumbnails of all the images.
image_folder = '/path/to/image/folder'
images = []
for filepath in Path(image_folder).iterdir():
    img = Image.open(filepath)
    w, h = img.size
    if w > h:
        f = 100 / w
        nw, nh = 100, int(f*h)
    else:
        f = 100 / h
        nw, nh = int(f*w), 100
    # Offsets to center thumbnail within (100, 100).
    woff, hoff = (100-nw) // 2, (100-nh) // 2
    img = img.resize((nw, nh), Image.BICUBIC)  # Shrink so largest dimen is 100.
    thumbnail = Image.new('RGBA', (100, 100), (255, 255, 255, 0))  # Blank.
    thumbnail.paste(img, (woff, hoff))  # Offset keep it centered.
    images.append(ImageTk.PhotoImage(thumbnail))

names = ['Name 1', 'Name 2', 'Name 3', 'Name 4']

def get_images():
    """Create all image and name Label pairs but initially  hidden."""
    global image_labels, name_labels

    image_labels, name_labels  = [], []
    for i, (img, name) in enumerate(zip(images, names)):
        image_label = Label(root, image=img)
        image_label.grid(row=1, column=2)
        image_labels.append(image_label)

        name_label = Label(root, text=name)
        name_label.grid(row=2, column=2)
        name_labels.append(name_label)

        hide(i)

def hide(i):
    """Hide specified image and name pair."""
    image_labels[i].grid_remove()
    name_labels[i].grid_remove()

def show(i):
    """Unhide specified image and name pair."""
    image_labels[i].grid()
    name_labels[i].grid()

def shift(direction):
    """Display the image and pair before or after the current one that is
    `direction` steps away (usually +/-1).
    """
    global current
    hide(current)
    current = (current + direction) % len(images)
    show(current)


left_button = Button(root, text="Left", command=lambda: shift(-1))
left_button.grid(row=2, column=1)

right_button = Button(root, text="Right", command=lambda: shift(+1))
right_button.grid(row=2, column=3)

get_images()
current = 0  # Currently displayed image.
show(current)

root.mainloop()

Screenshot of it running:

screenshot

于 2021-08-08T09:19:52.923 回答
1

左移或右移时应该只更新图像标签,而不是创建新标签。使用模数%找出下一回合。

为了减少代码和可执行文件,我在这里使用 PySimpleGUI 中的图像数据和图像的简单名称。

import tkinter as tk
import PySimpleGUI as sg

def shift(num):
    global index
    index = (index + num) % size
    label1.configure(image=images[index])
    label2.configure(text =labels[index])

root = tk.Tk()

images = [tk.PhotoImage(data=image) for image in sg.EMOJI_BASE64_HAPPY_LIST]
size = len(images)
labels = [f'Image {i:0>2d}' for i in range(size)]
index = 0

label1 = tk.Label(root, image=images[index])
label1.grid(row=1, column=2)
label2 = tk.Label(root, text=labels[index])
label2.grid(row=2, column=2)

button1 = tk.Button(root, text="<LEFT",  width=6, anchor='center', command=lambda num=-1:shift(num))
button1.grid(row=1, column=1)
button2 = tk.Button(root, text="RIGHT>", width=6, anchor='center', command=lambda num=+1:shift(num))
button2.grid(row=1, column=3)

root.mainloop()

在此处输入图像描述

于 2021-08-08T07:55:43.080 回答
0

你可以试试这个:

from tkinter import Tk,Label,Button
from PIL import ImageTk,Image
import io
import requests
import urllib 

root=Tk()

count=0 # To know the current image and label
urls=[url,url1,url2,url3]
labels=["label 1","label 2","label 3","label 4"]

images=[]
for ur in urls:
    raw_data = urllib.request.urlopen(ur).read()
    im = Image.open(io.BytesIO(raw_data))
    image = ImageTk.PhotoImage(im)
    images.append(image)

def change(direction): # Function to change image
    global count
    if direction=="left":
        if count<=0:
            count=len(urls)-1
        else:
            count-=1
    else:
        if count>=len(urls)-1:
            count=0
        else:
            count+=1
    name.config(text=labels[count])
    image_label.config(image=images[count])

Label(root).grid(row=1,column=1)
image_label=Label(root,image=images[count])
image_label.grid(row=1,column=2)

left_button=Button(root,text="Left",command=lambda : change("left"))
left_button.grid(row=2,column=1)

name=Label(root,text=labels[count])
name.grid(row=2,column=2)

right_button=Button(root,text="Right",command=lambda : change("right"))
right_button.grid(row=2,column=3)

root.mainloop()
于 2021-08-08T06:56:55.930 回答