Olej писал(а):
Вот такой UI построен с помощью Pygubu...
И код для него:
Код: Выделить всё
#!/usr/bin/python3
# -*- coding: utf-8 -*-
from __future__ import print_function
import os, argparse, sys
from PIL import Image, ImageTk
import time
try:
import tkinter as tk # for python 3
from tkinter import filedialog
except:
import Tkinter as tk # for python 2
import tkFileDialog as filedialog
import pygubu
parser = argparse.ArgumentParser() # construct the argument parse
parser.add_argument( '-v', '--verbose', action = 'count', help = 'increase output verbosity' )
args = vars( parser.parse_args() )
debug = 0 # verbose level
if args[ 'verbose' ] != None:
debug = int( args[ 'verbose' ] )
class Application:
def __init__( self, master ):
self.builder = builder = pygubu.Builder() # Create a builder
builder.add_from_file( 'xknown.ui' ) # Load an ui file
self.mainwindow = builder.get_object( 'Frame_1', master ) # Create the widget using a master as parent
master.resizable( width = False, height = False )
master.protocol( "WM_DELETE_WINDOW", self.on_close_window )
master.bind( '<Escape>', self.on_close_window ) # Esc interrupt
master.title( 'known face image load' )
self.c1 = builder.get_object( 'Canvas_1' ) # canvas for image
builder.get_object( 'Button_1' )[ 'command' ] = self.on_select
builder.get_object( 'Button_2' )[ 'command' ] = self.on_send
self.dir_name = './' # last directory
self.title = '' # last image path
def on_select( self ):
options = { # define options for deleting
'title' : 'Select image file',
'filetypes' : [ ( "Image", ("*.jpg","*.png", "*.bmp" ) ),
( "Other", ("*.ppm","*.pgm" ) ),
( "All files", "*.*" ) ],
'initialdir' : self.dir_name
}
title = filedialog.askopenfilename( **options )
if 0 == len( title ): return # cancel
try:
image = Image.open( title ) # PIL image
except OSError:
print( "it's not a image: {}".format( title ) )
return
self.title = title
self.dir_name = self.title[ 0 : self.title.rfind( os.sep ) ]
if debug:
print( 'selected image file: {}'.format( self.title ) )
if debug > 1:
height = image.height; width = image.width
print( 'PIL: w={} , h={}'.format( width, height ) )
self.tkimg = ImageTk.PhotoImage( image ) # Tk image
if debug > 1:
print( 'ImageTk: w={} , h={}'.format( self.tkimg.width(), self.tkimg.height() ) )
self.c1.configure( width = self.tkimg.width(), height = self.tkimg.height() )
brd = float( self.c1[ 'borderwidth' ] )
self.c1.create_image( self.tkimg.width() / 2 + brd, self.tkimg.height() / 2 + brd, image = self.tkimg )
def on_send( self ):
if '' == self.title:
print( 'error: image file not selected' )
return
print( 'will be send: {}'.format( self.title ) )
def on_close_window( self, event = None ):
self.mainwindow.master.destroy() # Call destroy on toplevel to finish program
root = tk.Tk()
app = Application( root )
root.mainloop()
Выполнение:
Код: Выделить всё
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud/Pygubu$ python2 xknown.py -v
selected image file: /home/olej/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud/Pygubu/Egor2.5.jpg
olej@ACER:~/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud/Pygubu$ python3 xknown.py -v
selected image file: /home/olej/2019_WORK/own.WORK/AplitSoft/FaceDL/cloud/Pygubu/Egor2.5.jpg
P.S. Я много провозился + потерял заметно времени на том, что Tk изображение ImageTk.PhotoImage() должно быть
обязательно членом класса, а не локальной переменной метода - иначе оно просто перезатирается при следующем цикле root.mainloop():
Код: Выделить всё
self.tkimg = ImageTk.PhotoImage( image ) # Tk image
В отличие от PIL изображения, которое вполне достаточно локально: