Python: Tkinter GUI

Вопросы написания собственного программного кода (на любых языках)

Модератор: Olej

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Python - графика

Непрочитанное сообщение Olej » 27 фев 2019, 13:13

Относительно Rapyd-Tk:
Olej писал(а): Вот рекомендуют для этого: Rapyd-Tk
An open-source application development environment for Python/Tkinter
Last updated 2018-03-28
Из их README.TXT :
This is Rapyd-Tk, a GUI program for creating and maintaining applications written using Python and Tkinter.

Rapyd Copyright 2005-2014 Cam Farnell

...
Rapyd requires Python version 2.5 or greater.
Rapyd does NOT run under Python 3.x.
1. Проект заморожен на уровне 2014 года
2. Меня он не устраивает в смысле Python 3

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Python - графика

Непрочитанное сообщение Olej » 27 фев 2019, 14:21

Следующий - Pygubu:
Olej писал(а):Обращаем внимание на дату последней ревизии - месяц назад!
Ничего в обновлениях там не поменялось:

Код: Выделить всё

olej@ACER:~$ sudo pip3 install -U pygubu
Requirement already up-to-date: pygubu in /usr/local/lib/python3.7/dist-packages (0.9.8.2)
Requirement already satisfied, skipping upgrade: appdirs>=1.3 in /usr/local/lib/python3.7/dist-packages (from pygubu) (1.4.3)
Для Python 2 (исполняющей системы!) можно доустановить:

Код: Выделить всё

olej@ACER:~$ sudo pip2 install -U pygubu
DEPRECATION: Python 2.7 will reach the end of its life on January 1st, 2020. Please upgrade your Python as Python 2.7 won't be maintained after that date. A future version of pip will drop support for Python 2.7.
Collecting pygubu
  Downloading https://files.pythonhosted.org/packages/dd/06/a968654f10b68e8860e9486b9d0fafb5076fa1a2f3aa1a081b1e5d5b5322/pygubu-0.9.8.2.tar.gz (122kB)
    100% |████████████████████████████████| 122kB 988kB/s 
Collecting appdirs>=1.3 (from pygubu)
  Using cached https://files.pythonhosted.org/packages/56/eb/810e700ed1349edde4cbdc1b2a21e28cdf115f9faf263f6bbf8447c1abf3/appdirs-1.4.3-py2.py3-none-any.whl
Building wheels for collected packages: pygubu
  Building wheel for pygubu (setup.py) ... done
  Stored in directory: /root/.cache/pip/wheels/7d/82/a0/615284053b8e468f25f32131a21436b1eaeac485007186ce74
Successfully built pygubu
Installing collected packages: appdirs, pygubu
Successfully installed appdirs-1.4.3 pygubu-0.9.8.2
На GIT проекта есть достаточно хорошая документация: https://github.com/alejandroautalan/pygubu/wiki

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Python - графика

Непрочитанное сообщение Olej » 28 фев 2019, 13:00

Olej писал(а):Следующий - Pygubu:
Olej писал(а):Обращаем внимание на дату последней ревизии - месяц назад!
Всё равно пришлось сильно поуродоваться ... с компоновкой виджетов и их показом. Реакции на действия (кнопки, закрытие окна) мне так и не удалось прописать в визуальном построителе.
Такое впечатление, что это всё-таки довольно сырое любительское поделие, техописания часто не совпадают (отстают?) от реального поведения...
И тем не менее! Этим построителем удаётся создать компоновку виджетов гораздо лучше и проще, чем вручную расставляя циферки в коде ;-)

У меня стояла простенькая задача:
- выбирать визуально файлы с изображением лиц ...
- просматривать изображения...
- и отсылать их на облачный сервер для распознавания изображённых лиц
- и всё это, ещё, должно работать и в Python 3 (приоритетно), и в Python 2.

Вот такой UI построен с помощью Pygubu... примерно так этот процесс выглядит:
Вложения
p3.png

Аватара пользователя
Olej
Писатель
Сообщения: 21336
Зарегистрирован: 24 сен 2011, 14:22
Откуда: Харьков
Контактная информация:

Re: Python - графика

Непрочитанное сообщение Olej » 19 янв 2023, 03:27

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
p4.png
P.S. Я много провозился + потерял заметно времени на том, что Tk изображение ImageTk.PhotoImage() должно быть обязательно членом класса, а не локальной переменной метода - иначе оно просто перезатирается при следующем цикле root.mainloop():

Код: Выделить всё

self.tkimg = ImageTk.PhotoImage( image )                  # Tk image
В отличие от PIL изображения, которое вполне достаточно локально:

Код: Выделить всё

image = Image.open( title )                           # PIL image 
Вложения
xknown_demo.py
(4.03 КБ) 86 скачиваний


Тема поднималась пользователем Olej 19 янв 2023, 03:27.

Ответить

Вернуться в «Программирование»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 8 гостей