Visualizza post

Questa sezione ti permette di visualizzare tutti i post inviati da questo utente. N.B: puoi vedere solo i post relativi alle aree dove hai l'accesso.


Topics - nuzzopippo

Pagine: [1] 2
1
Base / Valutazione tipi di variabile, ne parliamo un po'?
« il: Settembre 10, 2020, 13:47 »
Saluti a Voi :)

Pur non interessandomi molto a tkinter, ogni tanto lo riprendo in mano, al momento sto approfittando di un periodo di "stanca" per proseguire un argomento già toppato in altri post tipo questo ed in parte anche proseguito, tipo qua, in sostanza sto provando  a progettare un generico oggetto "tabella" da utilizzarsi poi in GUI tkinker.

Ora sto provando a progettare un processo, opzionale, di valutazione dei tipi di dati, ed allo stato sto prevedendo che tale valutazione venga effettuata da un oggetto di supporto alla tabella che, a richiesta, fornisca una "riga" di widget configurata, per colori, allineamenti e fonts, secondo parametri impostati, la tabella si occuperà di geometria, popolamento e binding.

Riguardo alla "definizione" delle tipologie di widget, per la valutazione, mi appoggio ad un dizionario che associa a delle "categorie" di dati vari sub-classamenti di widget
	data_types = {'text': DCEntry,        # casella di testo DCEntry allineato a destra
  'numeric': DCEntry,     # casella di testo DCEntry allineato a sinistra
  'date': DCEntry,   # casella di testo DCEntry allineato centrato
  'boolean': DCCheck,     # casella di spunta
  'image': DCCanvas,      # PhotoImage DCCanvas
  'collection': DCCombo,  # Lista, tupla o set DCCombo
  'label': DCLabel        # testo fisso DCLabel allineato a destra
}


e le chiavi del dizionario definiranno una lista definente i controlli da utilizzarsi, tale definizione può essere fornita direttamente dall'esterno oppure può esserne invocata la
definizione fornendo una lista di "oggetti" rappresentanti le tipologie dei dati da
rappresentare.

def evaluate_types(self, data):
'''
Esegue la valutazione di una riga dati per determinare il tipo di
controllo da utilizzare.

parametri : data - una lista di oggetti rappresentanti lo schema dei
                   dati da trattare.
'''
types = []
for i in len(data):
var = data[i]
if 'bool' in type(var):
types.append('boolean')
elif 'int' in type(var) or 'float' in type(var):
types.append('numeric')
elif 'datetime' in type(var):
type.append('date')
elif 'list' in type(var) or 'tuple' in type(var) or 'set' in type(var):
types.append('collection')
elif 'tkinter.PhotoImage' in type(var):
types.append('image')
else:
types.append('text')
self._style[controls][types] = types


... e qui mi son fermato a riflettere un po', in particolare inserendo la valutazione di "datetime", essendo la stessa una classe (come per altro PhotoImage) e non una tipologia builtin.
In effetti, pensandoci, non necessariamente una data proviene da un "datetime" (c'è anche "time" p.e, ol altro), così come una immagine non necessariamente è una "tkintr.PhotoImage"

... tale considerazione mi fa venire il dubbio che il tentativo di "generalizzazione" che sto cercando di fare sia troppo semplicistico, pur essendo ragionevolmente convinto che "funzionerebbe" in linea di massima.

Riferendo ai tipi di dato da valutare, in genere, Voi cosa ne pensate di un approccio di tal tipo?, pensate che vi siano ulteriori da tener presenti o migliori approcci?

Grazie per l'attenzione, ciao :)

2
wxPython / [Risolto]Installare wxPython in un venv sotto Linux
« il: Luglio 23, 2020, 11:54 »
I miei saluti.

Utilizzo una distribuzione Linux (Ubuntu 18.04) che di default utilizza la versione 3.6.9 di python (oltre la 2.7.x).
In un venv ho installato la versione "minimale" di python 3.8.0 al fine di eseguire test più conformi alle ultime caratteristiche del linguaggio.
 ... per proporre un esempio in altro forum, mi è venuto in mente di adattare un piccolo esempio di programma asincrono sviluppato in detto venv e di installare nello stesso ambiente le wx, sono sorti dei problemi che ho cercato di affrontare, in ultimo mi son bloccato seguendo i passi in questa pagina, tutto è andato bene sino al make, ma all'avvio della compilazione :
 Running command: build_py
  Checking for /tmp/pip-req-build-td89ziml/bin/waf-2.0.19...
  "/home/nuzzopippo/py_workspace/p38/p38b_v/bin/python" /tmp/pip-req-build-td89ziml/bin/waf-2.0.19 --wx_config=/tmp/pip-req-build-td89ziml/build/wxbld/gtk3/wx-config --gtk3 --python="/home/nuzzopippo/py_workspace/p38/p38b_v/bin/python" --out=build/waf/3.8/gtk3 configure build
  Setting top to                           : /tmp/pip-req-build-td89ziml
  Setting out to                           : /tmp/pip-req-build-td89ziml/build/waf/3.8/gtk3
  Checking for 'gcc' (C compiler)          : /usr/bin/gcc
  Checking for 'g++' (C++ compiler)        : /usr/bin/g++
  Checking for program 'python'            : /home/nuzzopippo/py_workspace/p38/p38b_v/bin/python
  Checking for python version >= 2.7.0     : 3.8.0
  python-config                            : not found
  Checking for library python3.8 in LIBDIR : not found
  Checking for library python3.8 in python_LIBPL : not found
  Checking for library python3.8 in $prefix/libs : not found
  Checking for library python3.8m in LIBDIR      : not found
  Checking for library python3.8m in python_LIBPL : not found
  Checking for library python3.8m in $prefix/libs : not found
  Checking for library python38 in LIBDIR         : not found
  Checking for library python38 in python_LIBPL   : not found
  Checking for library python38 in $prefix/libs   : not found
  Checking for header Python.h                    : Distutils not installed? Broken python installation? Get python-config now!
  The configuration failed
  (complete log in /tmp/pip-req-build-td89ziml/build/waf/3.8/gtk3/config.log)


Mi sembra di capire il "primo" dei problemi sia che non trovi "python-config" nell'ambiente virtuale che però era già li installato
(p38b_v) NzP:~$ pip install python-config
Requirement already satisfied: python-config in ./p38b_v/lib/python3.8/site-packages (0.1.2)
(p38b_v) NzP:~$

Ovviamente, mi ci son perso riguardo nell'insieme di librerie 3.8 non trovate ed il resto del chilometrico output a video. Purtroppo non mi è neanche riusciuscito di trovare il log del processo in "/tmp" (mancati permessi in scrittura, probabilmente) e non so che pesci prendere ... avete qualche suggerimento?

Grazie dell'attenzione :)

3
Base / Un utilizzo "strano" di locals e vars
« il: Giugno 12, 2020, 11:25 »
I miei saluti.

Intrigato dalla seguente domanda :
Citazione
E' possibile in Python creare una lista o un dizionario di tipi pronti per essere istanziati?

Ho trovato possibile risposta mediante l'utilizzo delle funzioni builtins "vars()" e "locals()", utilizzate in tale modo :

>>> class Anagrafica:
def __init__(self, cognome, nome):
self.cognome = cognome
self.nome = nome
def __str__(self):
return self.nome + ' ' + self.cognome


>>> from math import sqrt as radice_quadrata
>>> class_and_func = {'anag': 'Anagrafica',
      'rad' : 'radice_quadrata'
      }
>>> n = locals()[class_and_func['anag']]('nuzzo', 'pippo')
>>> print(n)
pippo nuzzo
>>> type(n)
<class '__main__.Anagrafica'>
>>> vars(n)
{'cognome': 'nuzzo', 'nome': 'pippo'}
>>> num = locals()[class_and_func['rad']](9)
>>> print(num)
3.0
>>>


Ora, lo scopo di entrambe le funzioni builtin citate è quello di restituire dei "dizionari", locals del "current scope's local variables", vars del dizionario di un "oggetto", come mostrato nel codice, anche se utilizzato senza argomenti funziona come locals. Circa la modalità d'uso di locals (del suo equivalente "vars()") su applicata non ho trovato documentazione.

Mi sembra evidente che spulciando il dizionario restituito da "locals()" con la chiave definita come in esempio si stia, di fatto, istanziando una classe od invocando una funziona definita nello scope locale ... niente di strano, tutto sommato ma mi chiedo se effettuare tal genere di operazioni sia una modalità "corretta" o, invece, soggetta a "complicazioni" varie.

Per altro, una certo "prurito" alle mani viene dal provare la bultin "globals" ma forse è meglio attendere pensieri più profondi dei miei ;)

4
ForumPython.it cafè / ORM : quando sono utili?
« il: Marzo 19, 2020, 08:14 »
Ciao

Dato che sto avendo un po' di tempo libero sto anche cercando di curiosare in giro e "vedere un po'" di qualcosa che non conosco per eventualmente integrarlo nelle mie prove.

Ieri sera ho iniziato a curiosare, da qui, in merito ad sqlalchemy ... roba complessa, mi sembra di capire, una astrazione che si astrae dalle specifiche dei singoli dialetti SQL dei motori di database supportati ma che richiede uno studio, tanto della libreria quanto della pianificazione riveniente dal suo uso, per molti versi anche più intenso di quello necessario ad un utilizzo diretto dello SQL, la cui conoscenza (unitamente al generico funzionamento dei db) comunque è presupposto necessario.

Certamente, un mezzo utile se si devono affrontare basi dati eterogenee ma mi viene il dubbio se e quanto possano essere utili a livello amatoriale ... mi spiego : un dilettante, seppur appassionato, avrà normalmente quale target piccoli applicativi, al più utilizzerà uno o due distinti sistemi di database (sqllite/access probabilmente) e sempre gli stessi, in tale condizioni (le mie, p.e.) vale la pena di misurarsi con dette astrazioni e sovrastrutture? E se si, perché?

Cosa ne pensate Voi, sulla questione?

Preciso che NON sto chiedendo supporto in merito, tant'è che ho postato al bar, solo di conoscere pensiero e motivazioni di chi voglia esporle, avanzato o meno che sia.

Ciao :)

5
ForumPython.it cafè / Potrebbe interessare un "tip"?
« il: Marzo 04, 2020, 20:40 »
Domanda rivolta agli "apprendisti" come me.

Recentemente ho rinverdito alcune cosette viste tempo fa ed utilizzato dei documenti Libreoffice/Openoffice writer (*.odt) come "template" da compilare poi con processi python che utilizzano la libreria odfpy, la faccenda è molto semplice per documenti a punti di inserimento fissi, un po' meno immediata se ci si propone una rappresentazione "tabellare" ma, comunque, abbastanza semplice.

So bene che la maggior parte utilizza metodi analoghi per documenti Microsoft Office, molto più diffusi e documentati, in ogni modo, da buon "linuxaro" preferisco i formati "aperti", pensate possa interessare un tip in merito a quanto sopra?

6
I miei saluti.

Mi trovo a dover risolvere, quanto prima mi riesce, un seccante problema sul lavoro. Ciò che dovrei fare, in sostanza, è creare un demone su di una debian da lanciare all'avvio che resti in ascolto su di una porta e provveda ad intermediare delle richieste di dati o di inserimento, su server PostgreSQL, oltre che compilare dei documenti in formato otd ed inviarli ai richiedenti.
La parte server dovrei scriverla in python (vorrei evitare java su quella macchina), i client saranno scritti in java (versioni windows obsolete), applicazioni desktop.

Riguardo Postgres ed i documenti otd non ho problemi, molta incertezza mi nasce in merito alle comunicazioni di rete, al momento sarei orientato verso i socket ed il multi-threading ... entrambi argomenti molto da approfondire, in particolare mi manca il "flush" nelle comunicazioni e il threading non lo ancora proprio guardato in python.

Qualcuno di Voi è a conoscenza di qualche mezzo/tecnica utile allo che possa acquisirsi con una certa "rapidità" da potermi suggerire?
(al momento è un "basta che funzioni") ;)

Grazie dell'attenzione, ciao :)

7
I miei saluti :)

Essendomi stata richiesto, in ufficio, di rendere disponibile una piccola utilità che mi hanno visto utilizzare (uno script bash) ho preso la palla al balzo per realizzarla in python (view testuale, x me, e grafica, per gli altri : ottimo per studiarsi MVC), in un giorno è mezzo ho realizzato la parte funzionale ... poi, sottovalutando la cosa, ho pensato di mettere una "ciliegina sulla torta", nella parte grafica, ossia di rendere possibile l'apertura di files (testo o pdf nel caso) con le applicazioni grafiche predefinite nel sistema.

... ci ho perso su un altro giorno (scoprendo un bel po' di cose da studiarmi), sconfortandomi sul sorgente di "platform" (solo windows ha 'na tragedia di versioni)  alla fine ho strutturato poco fa una rozza funzione sulla base di ricerche varie tutte da approfondire. La funzione sarebbe questa :

def show_file(f):
    '''
    "Cerca" di aprire un file con la applicazione grafica predefinita nel sistema

    return
    --- True se riesce ad aprirlo
        ovvero
        False se non ci riesce
    '''
    # tentativo con linux
    try:
        subprocess.run(['xdg-open', f], check=True)
        return True
    except:
        pass
    # tentativo con windows
    try:
        # os.startfile(f) # ? non esiste in os
        os.system('start ' + f)
        return True
    except:
        pass
    # forse mac?
    try:
        subprocess.call('open', f)
        return True
    except:
        pass
    # ... vabbeh, ci ho provato
    return False

Riguardo linux funziona, per windows vedrò domani (per mac chissa :( )

... Non è molto importante e certamente ho molti aspetti da approfondire ma, dato che al momento il lavoro mi lascia pochissimo tempo, se ci fosse qualche suggerimento lo ascolterei con piacere.

Grazie dell'attenzione, ciao :)

8
I miei saluti

Nel corso dei miei tentativi di studio di alcuni pattern mi sono imbattuto in un tipo di notazione per me nuova in python, ossia la dichiarazione di tipo per parametri e return di un metodo/funzione (pep's 3107 e 484) ... devo dire che mi ha fatto piacere trovarle ma nel seguire un esempio così posto :

from abc import ABC, abstractmethod
from random import randrange
from typing import List

class Observer(ABC):
    '''
L'interfaccia di Observer dichiara il metodo di aggiornamento, utilizzato
dai subjects.
'''

    @abstractmethod
    def update(self, subject: Subject) -> None:
        '''
Riceve lo update da subject.
'''
        pass


class Subject(ABC):
    '''
Oggetto interfaccia, dichiara una serie di metodi per la gestione
di subscribers.
'''

    @abstractmethod
    def attach(self, observer: Observer) -> None:
        '''
...


Mi son reso conto che, almeno nella versione 3.6.9 di python che uso, la notazione è valida solo se il tipo di oggetto dichiarato quale parametro è definito precedentemente alla dichiarazione stessa, altrimenti si ha :

Python 3.6.9 (default, Nov  7 2019, 10:44:02)
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license()" for more information.
>>>
======= RESTART: /media/nuzzopippo/progetti/mvc_example/observer_ex.py =======
Traceback (most recent call last):
  File "/media/nuzzopippo/progetti/mvc_example/observer_ex.py", line 7, in <module>
    class Observer(ABC):
  File "/media/nuzzopippo/progetti/mvc_example/observer_ex.py", line 14, in Observer
    def update(self, subject: Subject) -> None:
NameError: name 'Subject' is not defined
>>>


Problema aggirabile facilmente, omettendo la dichiarazione di tipo
======= RESTART: /media/nuzzopippo/progetti/mvc_example/observer_ex.py =======
Subject: Aggiunto un observer.
Subject: Aggiunto un observer.


metodo che però non trovo gradevole, provato a rileggere dette pep's con l'unico risultato di "incartarmi", ho capito poco e non ne sono venuto a capo (anzi ho trovato un sacco di ulteriori cose da "vedere"), anche se ho il sospetto manchi un
from __future__ import annotations

disponibile da python 3.7 e che sarà "consolidato" in python 4.0

A parte il dichiarare gli oggetti "parametro" in moduli diversi in caso di incroci, o di omettere tale dichiarazione, qualcuno conosce una metodologia più corretta per la definizione di tali parametri incrociando oggetti definiti nello stesso modulo?

9
Tkinter / Tooltip in tkinter
« il: Gennaio 06, 2020, 13:26 »
Saluti a Voi :)

Il presente post NON È una richiesta di supporto ma una "offerta" che porgo agli utenti che stanno iniziando con python e che, come constato, si avventurano a programmare GUI con tkinter.

Avendo deciso di fare, solo per sperimentare alcuni pattern (MVC-Observer), quello che sarà il mio ultimo "esperimento" con tkinter, poi passerò ad altro framework, organizzandolo "come piace a me", ossia con tutti gli "accorgimenti" che mi piace realizzare in una finestra grafica, Uno dei detti "accorgimenti" e applicare "tooltip", tanto ai vari widget, quanto ai menu, cosa che in tkinter non è possibile fare a meno di non integrare nel proprio codice l'obsoleta libreria TIX ed utilizzare il controllo aggiuntivo "balloon" ... cosa che non ho voluto fare.

Con l'aiuto di San Google e di un paio di classi, in parte personalizzate, trovare su stackoverflow, citata la fonte nella docs delle calssi che seguono, ho realizzato un sistema di tooltip utilizzabili in tkinter senza aggiungere ulteriori librerie, articolato in tre classi.

La prima "CreaToolTip" è dedicata ai widget "comuni" e si invoca chiamando "tooltip = CreaToolTip(widget, testo)", ovvio che è solo uno schema di chiamata, ove "widget" è il controllo cui deve essere applicato il tootip e "testo" è il testo da applicarsi, va da se che un toltip definito in una classe deve essere memorizzato quale variabile di istanza della classe stessa.

Le altre due classi sono dedicare a far apparire dei tooltip in un menu tkinter, applicati ai soli item "command", ed è ottenuta sub-classando la classe "Menu" di tkinter nella classe "MenuTooltip" che provvede a memorizzare indice e tooltip di un item "command" definito, quindi ad intercettare il passaggio del mouse esponendo il tooltip corrispondente all'item sottostante il puntatore. La definizione del tooltip avviene semplicemente aggiungendo un ulteriore argomento "tooltip=testo_da_mostrare" in una invocazione "menu.add_command()". Poi provvede la classe "MenuTooltip ad invocare la classe "ToolTipWin" che provvede a visalizzare effettivamente il tooltip.
Preciso che dette classi sono limitate a ciò che ritengo mi serva per lo studio per cui sono state create, potrebbero facilmente essere ridotte a due le classi necessarie ed espanse le tipologie di item servite, compito degli eventuali interessati, se vogliono.

In successione a questo post ne farò un altro per fornirvi un esempio funzionale di test, sarebbe troppo lungo per un unico post dato che una interfaccia che stavo preparando per miei scopi e durante la cui realizzazione mi è venuto il pensiero che questo argomento potrebbe interessare altri utenti del Forum.

Intanto, il codice delle classi definenti i tooltip, 202 righe ;
# -*- coding: utf-8 -*-

import tkinter as tk

# *** CLASSI DI UTILITÀ DERIVATE DA ALTRE TROVATE IN GIRO ED ADATTATE ***

class CreaToolTip(object):
    '''
Crea un tooltip per un generico widget.

Esempio originale tratto da stackoverflow, indirizzo:
https://stackoverflow.com/questions/3221956/how-do-i-display-tooltips-in-tkinter

eseguite minime personalizzazioni.
'''
    def __init__(self, controllo, msg=''):
        self.attesa = 500                # Tempo di attesa in millisecondi
        self.lunghezza = 300             # dimensione del messaggio in pixel
        self.controllo = controllo
        self.testo = msg
        # Utilizza gli eventi del controllo chiamante
        self.controllo.bind('<Enter>', self.avvia)
        self.controllo.bind('<Leave>', self.chiudi)
        self.controllo.bind('<ButtonPress>', self.chiudi)
        self.id = None
        self.tw = None

    def avvia(self, event=None):
        self.schedule()

    def chiudi(self, event=None):
        self.unschedule()
        self.nasconditip()

    def schedule(self):
        self.unschedule()
        self.id = self.controllo.after(self.attesa, self.mostratip)

    def unschedule(self):
        iden = self.id
        self.id = None
        if iden:
            self.controllo.after_cancel(iden)

    def mostratip(self, event=None):
        x = y = 0
        x, y, cx, cy = self.controllo.bbox('insert')
        x += self.controllo.winfo_rootx() + 25
        y += self.controllo.winfo_rooty() + 20
        # crea una finestra toplevel con padre il controllo
        self.tw = tk.Toplevel(self.controllo)
        # lascia solo la label e rimuove gli elementi della finestra
        self.tw.wm_overrideredirect(True)
        self.tw.wm_geometry('+%d+%d' % (x, y))
        messaggio = tk.Label(self.tw,
                             text=self.testo,
                             justify='left',
                             background='#f6f6e3',
                             relief='solid',
                             borderwidth=1,
                             wraplength=self.lunghezza
                             )
        messaggio.pack(ipadx=1)

    def nasconditip(self):
        tw = self.tw
        self.tw = None
        if tw:
            tw.destroy()



class MenuTooltip(tk.Menu):
    '''
    da https://stackoverflow.com/questions/55316791/how-can-i-add-a-tooltip-to-menu-item
    permette di aggiungere un tooltip ai menu-items.
    Introdotte variazioni funzionali rispetto all'esempio citato.
    '''
    def __init__(self, parent):
        """
        :parametro parent: il master del Menu, può essere 'root' o 'Menubar'
         .tooltip == Lista di tuple (yposition, text)
         .tooltip_active == Indice (0-based) del Tooltip attivo
         eventi intercettati <Leave>, <Motion>
        """
        super().__init__(parent, tearoff=0)
        self.tooltip = []
        self.tooltip_active = None
        self.tooltip_win = None

        self.bind('<Leave>', self.leave)
        self.bind('<Motion>', self.on_motion)

    def add_command(self, *cnf, **kwargs):
        tooltip = kwargs.get('tooltip')
        if tooltip:
            del kwargs['tooltip']
        super().add_command(*cnf, **kwargs)
        # chiede l'indice dell'ultimo command
        u_command = self.index("end")
        self.add_tooltip(u_command, tooltip)

    def add_tooltip(self, index, tooltip):
        """
        :parametro index  : Indice (0-based) degli item del Menu
        :parametro tooltip: Testo da mostrare quale Tooltip
        :return: None
        """
        self.tooltip.append((self.yposition(index) + 2, tooltip))

    def on_motion(self, event):
        """
        Cicla i .tooltip per trovare il Menu Item
        """
        for idx in range(len(self.tooltip) - 1, -1, -1):
            if event.y >= self.tooltip[idx][0]:
                x = event.x_root
                y = event.y_root
                point = (x, y)
                self.show_tooltip(idx, point)
                break

    def leave(self, event):
        """
        Distrugge il Tooltip corrente e resetta .tooltip_active a None
        """
        if not self.tooltip_active is None:
            # destroy(<tooltip_active>)
            if self.tooltip_win:
                self.tooltip_win.chiudi()
            self.tooltip_active = None

    def show_tooltip(self, idx, point):
        """
        Mostra il Tooltip se non presente, distrugge il Tooltip attivo
        :parametro idx: Indice del Tooltip mostrato
        :point        : coordinate di posizionamento del tooltip
        :return: None
        """
        if self.tooltip_active != idx:
            # destroy(<tooltip_active>)
            if self.tooltip_win:
                self.tooltip_win.chiudi()
            # create new tooltip
            self.tooltip_active = idx
            msg = self.tooltip[idx][1]
            self.tooltip_win = ToolTipWin(self, point, msg)
            self.tooltip_win.avvia()


# *** MIE CLASSI ***

class ToolTipWin(object):
    '''
Ricodifica della classe CreaToolTip mirata alla esposizione di tooltip
in un menu tkinter (gli oggetti items non vengono restituiti quali widget)
'''
    def __init__(self, ctrl, point, msg=''):
        self.attesa = 500
        self.lunghezza = 300
        self.ctrl = ctrl
        self.text = msg
        self.point = point
        self.id = None
        self.tw = None

    def avvia(self):
        self.unschedule()
        self.id = self.ctrl.after(self.attesa, self.mostra_tip)

    def chiudi(self):
        self.unschedule()
        self.nascondi_tip()

    def unschedule(self):
        iden = self.id
        self.id = None
        if iden:
            self.ctrl.after_cancel(iden)

    def mostra_tip(self):
        x, y = self.point
        # crea una finestra toplevel con padre il menu
        self.tw = tk.Toplevel(self.ctrl)
        # lascia solo la label e rimuove gli elementi della finestra
        self.tw.wm_overrideredirect(True)
        self.tw.wm_geometry('+%d+%d' % (x, y))
        messaggio = tk.Label(self.tw,
                            text=self.text,
                            justify='left',
                            background='#f6f6e3',
                            relief='solid',
                            borderwidth=1,
                            wraplength=self.lunghezza
                            )
        messaggio.pack(ipadx=1)

    def nascondi_tip(self):
        tw = self.tw
        self.tw = None
        if tw:
            tw.destroy()

10
Tkinter / [Risolto] Elenco nomi dei colori in tkinter
« il: Dicembre 03, 2019, 18:28 »
Signori, buona sera

Mi è venuto in mente di fare una dialog di selezione colori in tkinter basata sui nomi dei colori riconosciuti da tkinter e sto facendo qualche esperimento in merito.

La prima prova che mi è venuta in mente, è di popolare la finestra con una serie di label con assegnato il colore tramite il color-name (pessima idea, tempi biblici, troverò qualche altro modo).
Pur avendo trovato i nomi dei colori nella docs in questa pagina, data la pigrizia, ho pensato bene di andarmi a leggeri i nomi dei colori nel file "rgb.txt" di X11, in fondo quei nomi in tkinter si basano su X, applicandoli alle label, ne sono stati riconosciuti 751 su 753, contro i 760 presenti nel documento citato (colori mac e windows esclusi)

Ora, è banale che quei nomi di colore siano memorizzati da qualche parte in tkinter, dato che vengono riconosciuti.
Volendo evitare di scriverli nel codice e/o in un file (che comunque possiedo) ho cercato un metodo od una variabile che li contenga, tanto nella docs quanto leggendo direttamente il sorgente python delle tkinter, non cavandone un ragno dal buco e senza schiarirmi le idee (solo il vago sospetto siano nei binari).

Conoscete un metodo per "estrarre" l'elenco dei nomi di colore o, almeno, come stanno le cose?

Grazie dell'attenzione, ciao.

11
Buon giorno, signori.

Mi son trovato a dover affrontare un cambio della modalità della rete ethernet in ambito lavorativo che, per motivi vari, è passata dalla condizione di rete ad indirizzi TCP-IP fissi, sotto il controllo del personale interno, ad un sistema DHCP con controllo eterno (oltre tutto ben poco "disponibile" a dialogo ed integrazioni) che ha causato il crollo di tutte le applicazioni localmente sviluppate, tra cui alcune estremamente critiche.
Per le applicazioni critiche ho risolto creando una sotto-rete ad IP fissi e spostando nella stessa le macchine interessate alla gestione, negando qualsiasi comunicazione esterna.

Per quanto riguarda gli aspetti di mero servizio, ho risolto sviluppando dei prototipi in python per tentare l'individuazione in rete dei server ed una volta riuscita, traducendo i metodi in java/visual basic integrandoli nelle applicazioni interessate, lasciando il funzionamento nell'ambito della rete DHCP.

In questa seconda fascia, le tipologie di server interessati sono : PostgreSQL, FTP, SSH ed HTTP.
La strategia di approccio da me "ideata" è stata, preliminarmente :
- per i database, inserita una tavola con un campo identificativo specifico della base dati ed una tavola riferente agli altri server contenente i dati identificativi ed utenza necessari;
- per i server FTP inserendo stringhe identificative nel banner degli stessi;
- per gli SSH nessuna (li uso solo io);
- per gli HTTP spostando le porte di ascolto dei vari virtual-host e costruendo un launcher java per ovviare alla riveniente inutilità dei files "hosts" (la lan locale non dispone di server DNS, che poi bisognerebbe comunque trovare).

Dal punto di vista del software di ricognizione, ho realizzato due moduli, dei quali risparmio il codice, a meno che non lo si ritenga utile, il primo (~100 righe + test] dedicato a rilevare le schede fisiche di rete ed i relativi IP4 oltre che alla scansione delle porte di ascolto, tramite socket, nell'intervallo 1-254 delle sotto-reti individuate nella macchina, il secondo (~250 righe + test) si occupa di stabilire i tentativi di connessione ed identificazione dei server "giusti" (nella rete ho identificato diversi "servizi" che non sono locali).

Or bene, sono consapevole che la modalità su esposta, pur se funzionale è senz'altro rozza, non mi sono mai interessate le problematiche di "rete" ed ho dovuto improvvisare in fretta, la domanda è :

Siete a conoscenza di modalità migliori per impostare ed individuare in lan locale dei server di cui non conoscete l'indirizzo? E se si, sapreste darmi indicazione di dove/come acquisire le tecniche necessarie?

Grazie dell'attenzione, i miei saluti.

12
Base / [Risolto] Aggiornamento output nel terminale con end=''
« il: Ottobre 05, 2019, 18:49 »
Signori, i miei saluti.

In fase di test di una classe in sviluppo per un oggetto dedicato alla scansione di lan locale per l'individuazione di eventuali hosts  in ascolto ho riscontrato un curioso "effetto" utilizzando una istruzione
print('.', end='')

con output destinato ad un normale trminale bash : l'output relativo NON viene mostrato prima della conclusione del processo (un po' lunghetto).

Il problema si presenta anche in caso si utilizzi uno spazio quale terminazione del print mentre funziona regolarmente in caso di utilizzo di un newline.

... Curioso ma non stranissimo il fenomeno, mi sta facendo "incarognare" ma per quanto ci giri attorno e cerchi in rete non sto trovando soluzione (un time.sleep(qualcosa) non serve), non riesco a far aggiornare quel dannato output.
È probabile la "soluzione" sia banale ma proprio non mi riesce di immaginare dove altro cercarla ... qualcuno conosce la problematica?

Non credo se serva in merito, ma giusto in caso io ne sia inconsapevole causa, questo è l'oggetto che dovrebbe produrre quell'output (con tutte le "sporcature" del litigio

class ScanPortLan():
    '''
Esegue la scansione di una specifica porta su tutti gli indirizzi della rete
locale al fine di individuare su quali macchine vi è "qualcosa" in ascolto.
    '''
    def __init__(self, ip, porta):
        '''
Inizializzazione dell'oggetto, memorizza quali variabili di istanza l'indirizzo
locale e la porta da verificare.

Parametri : ip    - stringa dell'indirizzo ipv4 della macchina
            porta - porta da verificare
        '''
        self.ind_ascolto = []
        self.my_ip = ip
        self.porta = porta
        self.scan()
   
    def scan(self):
        '''
Tenta una connessione alla porta definita nel range 1/254 della rete locale,
escluso il proprio indirizzo.
Memorizza gli indirizzi che hanno dato risposta.
        '''
        base = self.my_ip.split('.')
        base_ind = '.'.join(base[:-1])
        for p in range(1, 255):
            curr_ip = base_ind + '.' + str(p)
            if curr_ip != self.my_ip:
                if self.connetti(curr_ip):
                    print('\n', curr_ip, '<-->', 'CONNESSO')
                    self.ind_ascolto.append(curr_ip)
                else:
                #print('.', end='')
                    #print('.', end=' ')
                    print('.', end='\n')
                    #print('.')
            time.sleep(0.5)
        print()
        print('Hosts in ascolto:')
        for ip in self.ind_ascolto:
            print('\t', ip)
   
    def connetti(self, ip):
        try:
            s = socket.socket(socket.AF_INET)
            s.settimeout(0.5)
            s.connect((ip, self.porta))
            result = True
        except OSError:
            result = False
        finally:
            if s:
                s.close()
        return result

Manca la restituzione di quanto trovato.

questa è la sua corrente invocazione di test

if __name__ == '__main__':
    llhr = LocalLanHdwRec()
    for ip in llhr.get_ip4():
        ScanPortLan(ip, 21)


e questo è un esempio della disdicevole casistica :

NzP:~$ python3 recognizer.py
^C..............Traceback (most recent call last):
  File "recognizer.py", line 106, in <module>
    ScanPortLan(ip, 21)
  File "recognizer.py", line 64, in __init__
    self.scan()
  File "recognizer.py", line 82, in scan
    time.sleep(0.5)
KeyboardInterrupt
NzP:~$ python3 recognizer.py


Ciao e grazie dell'attenzione :)

13
I miei saluti.

Per una "trasformazione" della lan locale, da IP statici definiti localmente a DHCP non controllabile localmente, mi sto ponendo domande su come individuare alcuni server in lan locale (database, ftp, ssh etc.) in un ambiente ad IP variabili.

La soluzione più immediata che mi è venuta in mente è individuare gli indirizzi tcp-ip locali alla macchina e poi fare una scansione del range 1 - 254 della sotto-rete locale per vedere su quali indirizzi le porte dei server sono aperte ed in ascolto.

Individuare gli indirizzi IP locali alla macchina mi è riuscito utilizzando il modulo "netifaces", in questo modo :
>>> import netifaces as ni
>>> nif = ni.interfaces()
>>> for scheda in nif:
print('Interfaccia :', scheda)
diz_ind = ni.ifaddresses(scheda)
for chiave in diz_ind.keys():
if chiave == 2:
print('%3s' % chiave, diz_ind[chiave])
print()


Interfaccia : lo
  2 [{'addr': '127.0.0.1', 'netmask': '255.0.0.0', 'peer': '127.0.0.1'}]

Interfaccia : enp2s0
  2 [{'addr': '192.168.60.28', 'netmask': '255.255.255.0', 'broadcast': '192.168.60.255'}]

>>>


Ma vorrei limitare le scansioni alle sole schede "fisiche" presenti nel sistema, evitando interfacce di loobpack e virtuali, è un po' che cerco nella documentazione ma non mi riesce di individuare niente di utile in merito a come effettuare una tale distinzione, avreste delle indicazioni da darmi in proposito?

Grazie dell'attenzione :)

14
I miei saluti a Voi.

Cercando di realizzare un "controllo" personalizzato (assemblando vari widget) ho provato, tra l'altro, una "composizione" che prevede l'utilizzo di una scrollbar non associata alla view di un secondo widget.
L'utilizzo della scrollbar è relazionato al solo scorrimento di un indice di lista dati.

La prova, tutto sommato, ha avuto successo, almeno in linea di massima, in questo modo :
dichiarazione nello __init_della classe :
        self.pivot_scroll = tk.Scrollbar(self,
                                         orient=tk.VERTICAL,
                                         jump=1,
                                         command=self._scrollEvent)

l'opzione "jump=1" è data per limitare gli eventi al solo rilascio del tasto del mouse

definizione del "set" per la scrollbar al caricamento dei dati :
    def set_data(self, dati):
        self.dati = dati
        self.pivot = 0
        for riga in self.rows:
            riga.clear()
        # configurazione scrollbarr
        self.pivot_scroll.set(0, len(self.dati) - self.righe)
        # fine per scroll
        self._refresh_rows()

ove viene impostato, per la scrollbar, un "intervallo" pari alla consistenza dei dati decurtata degli elementi visualizzati, tale impostazione è necessaria, in assenza si hanno "out of range" ad ogni evento proveniente dalla scrollbar

gestito valutando i dati passati dalla scrollbar al gestore (handler, se volete) associato
    def _scrollEvent(self, *L):
        """Gestisce lo scroll della vertical barr associata."""
        if not self.dati: return
        for elem in L: print(elem, end=' - ')
        print()
        op, valore = L[0], L[1]
        if op == 'scroll':
            modo = L[2]
            if modo == 'pages':
                val = int(valore) * self.righe
            else:
                val = int(valore)
            if (self.pivot + val) < 0:
                self.pivot = 0
            elif (self.pivot + val) > (len(self.dati) - self.righe):
                self.pivot = len(self.dati) - self.righe
            else:
                self.pivot += val
        elif op == 'moveto':
            self.pivot += int(len(self.dati) * float(valore)) - 1
            if self.pivot < 0:
                self.pivot = 0
            elif self.pivot > len(self.dati) - self.righe:
                self.pivot = len(self.dati) - self.righe
        self._refresh_rows()


Come detto, le impostazioni sopra per funzionare funzionano ma in modo insoddisfacente : lo slider della scrollbar assume la dimensione dell'intera area disponibile, cosa non sorprendente, e (questo è strano) si "ridimensiona" in caso di trascinamento a partire dai bordi estremi dello stesso, tale ridimensionamento permate e da quel momento è possibile "agganciare" e trascinare lo slider, la "precisione" lascia a desiderare ed il posizionamento effettivo dello slider è insussistente.
Se occorressero maggiori dettagli od una visualizzazione grafica della circostanza potete vedere qui, sono semplici appunti di apprendimento.

Non so se è possibile farlo ma vorrei realizzare un controllo adeguato della rappresentazione dei dati visualizzati in rapporto all'insieme degli stessi, il tutto completamente avulso da view di elementi grafici.
Ho molto cercato e letto ma ho trovato pochissimo, se non nulla, di specifico in merito ad una definizione  delle specifiche dello slider o, magari, ci sono incappato e non ho compreso, data la mia ignoranza dell'inglese.

Qualcuno di Voi avrebbe indicazioni e/o suggerimenti in merito?

Grazie dell'attenzione  :caffè:

15
Base / Storage parametri applicazione : un consiglio
« il: Aprile 20, 2019, 12:43 »
Buon giorno a Voi ... e buona Pasqua, data la prossimità :)

Desidererei un consiglio :
nei sistemi unix-like è ampiamente usato memorizzare parametri opzionali di una applicazione scelti da un utente in una direttrice nascosta nella home dell'utente, cosa semplice da realizzare con python

import os
...
def load_app_configurations():
    '''Acquisisce, se esistono, le scelte applicative salvate.'''
    home = os.path.expanduser('~')
    app_dir = os.path.join(home, '.app_name')
    if not os.path.exists(app_dir):
        os.mkdir(app_dir)

mi apprestavo ad utilizzare una tale metodologia ma mi son fermato un attimo, so che "funzionerebbe" anche in windows, almeno per alcune versioni, ma mi chiedo se esiste una qualche convenzione/linea guida in merito, almeno per l'ambito python ...  sapreste darmi suggerimenti in merito?

Pagine: [1] 2