2011-07-17 3 views
11

У меня есть несколько изображений, которые я хотел бы показать пользователю с Python. Пользователь должен ввести некоторое описание, а затем должно отображаться следующее изображение.Как закрыть изображение, показанное пользователю с помощью библиотеки изображений Python?

Это мой код:

#!/usr/bin/python 
# -*- coding: utf-8 -*- 

import os, glob 
from PIL import Image 

path = '/home/moose/my/path/' 
for infile in glob.glob(os.path.join(path, '*.png')): 
    im = Image.open(infile) 
    im.show() 
    value = raw_input("Description: ") 
    # store and do some other stuff. Now the image-window should get closed 

Это работает, но пользователь должен закрыть изображение себя. Могу ли я заставить python закрыть изображение после ввода описания?

Мне не нужен PIL. Если у вас есть другая идея с другой библиотекой/bash-программой (с подпроцессом), это тоже будет хорошо.

ответ

12

Метод show «в основном предназначен для целей отладки» и порождает внешний процесс, для которого вы не получаете дескриптора, поэтому вы не можете его убить надлежащим образом.

С PIL вы можете использовать один из своих графических интерфейсов, например ImageTk, ImageQt или ImageWin.

В противном случае, просто вручную нерест просмотра изображений из Python с subprocess модуля:

for infile in glob.glob(os.path.join(path, '*.png')): 
    viewer = subprocess.Popen(['some_viewer', infile]) 
    viewer.terminate() 
    viewer.kill() # make sure the viewer is gone; not needed on Windows 
+0

Привет larsmans, вот именно то, что я искал. Не могли бы вы внести вклад Popen в список (добавив [])? Без него это не сработает. Спасибо также за упоминание ImageTk и ImageQt, я посмотрю на них. –

+0

@moose: да, забыл '[]', извините. –

+1

Как использовать предварительный просмотр в OSX как 'some_viewer'? –

3

Я изменил this recipe до того, чтобы сделать некоторые изображения работы в Python. Он использует Tkinter, поэтому он не требует никаких модулей, кроме PIL.

'''This will simply go through each file in the current directory and 
try to display it. If the file is not an image then it will be skipped. 
Click on the image display window to go to the next image. 

Noah Spurrier 2007''' 
import os, sys 
import Tkinter 
import Image, ImageTk 

def button_click_exit_mainloop (event): 
    event.widget.quit() # this will cause mainloop to unblock. 

root = Tkinter.Tk() 
root.bind("<Button>", button_click_exit_mainloop) 
root.geometry('+%d+%d' % (100,100)) 
dirlist = os.listdir('.') 
old_label_image = None 
for f in dirlist: 
    try: 
     image1 = Image.open(f) 
     root.geometry('%dx%d' % (image1.size[0],image1.size[1])) 
     tkpi = ImageTk.PhotoImage(image1) 
     label_image = Tkinter.Label(root, image=tkpi) 
     label_image.place(x=0,y=0,width=image1.size[0],height=image1.size[1]) 
     root.title(f) 
     if old_label_image is not None: 
      old_label_image.destroy() 
     old_label_image = label_image 
     root.mainloop() # wait until user clicks the window 
    except Exception, e: 
     # This is used to skip anything not an image. 
     # Warning, this will hide other errors as well. 
     pass 
+0

Для этого требуется ImageTK. Но я только что нашел подходящий Ubuntu-Package: sudo apt-get install python-imaging-tk. Я что-то упускаю или не могу дать пользователю вход? Я хотел закрыть текущее окно и открыть следующий (или просто открыть следующий в текущем окне) без какого-либо другого взаимодействия с пользователем, чем писать описание (завершая ввод). –

+0

ImageTK должен поставляться с PIL ... Вы можете изменить окно и прикоснуться к текстовому полю и кнопке, если хотите. Мой 'Tkinter' очень старый, обычно я использую' wx'. –

7

psutil может получить PID из display процесса, созданного im.show() и убить процесс с этим PID на любой операционной системе:

import time 

import psutil 
from PIL import Image 

# open and show image 
im = Image.open('myImageFile.jpg') 
im.show() 

# display image for 10 seconds 
time.sleep(10) 

# hide image 
for proc in psutil.process_iter(): 
    if proc.name() == "display": 
     proc.kill() 
+3

Это не работает на mac osx –

+0

@IDelgado psutil должен работать под OS X. Просьба описать вашу проблему на [проблемах трекера проекта] (https://github.com/giampaolo/psutil/issues). – Bengt

+0

@Bengt После 'proc.name' метод, поэтому вы можете называть его как' proc.name() ', и только тогда будет работать. Пожалуйста, исправьте это, и вы, и вы получите голосование. – Geeocode

Смежные вопросы