2013-03-30 6 views
5

Sto sviluppando un demone di backup che verrà eseguito silenziosamente in background. Il demone si affida al software di backup duplicity, che al momento del backup richiede una chiave di crittografia. Non posso chiedere la password attraverso la console perché, ovviamente, il demone non ha accesso a tale.Il metodo più semplice per chiedere all'utente la password usando la finestra di dialogo grafica in Python?

Come posso creare facilmente un prompt che chiede all'utente di digitare una password e la restituisce all'applicazione (tramite una variabile Python)? Sto usando Python 2.7.

+0

È possibile utilizzare TkInter o PyQt? – chrisaycock

+0

Sì, non sono troppo preoccupato per le dipendenze extra. – liamzebedee

risposta

4
from Tkinter import * 

def getpwd(): 
    password = '' 
    root = Tk() 
    pwdbox = Entry(root, show = '*') 
    def onpwdentry(evt): 
     password = pwdbox.get() 
     root.destroy() 
    def onokclick(): 
     password = pwdbox.get() 
     root.destroy() 
    Label(root, text = 'Password').pack(side = 'top') 

    pwdbox.pack(side = 'top') 
    pwdbox.bind('<Return>', onpwdentry) 
    Button(root, command=onokclick, text = 'OK').pack(side = 'top') 

    root.mainloop() 
    return password 
+0

Non funziona per me. Ho risolto un problema con il riferimento a root prima definito. Ora posso visualizzare la finestra di dialogo, ma quando digito la password 1) ** i caratteri mostrano, invece dei punti neri ** e 2) quando premo return ** non viene restituito nulla da 'getpwd' **. Inoltre, ottengo un errore quando faccio clic su OK - onpwdentry() richiede esattamente 1 argomento Grazie per la risposta rapida. – liamzebedee

+0

Ok, l'ultima modifica dovrebbe risolvere i tuoi problemi. Per 1) imposto la proprietà "show" del widget Entry su "*", quindi mostrerà gli asterischi invece delle lettere. 2) è stato un errore incredibilmente stupido da parte mia: ho avuto la sottofunzione che restituiva la password, quando ovviamente volevo che la funzione principale lo restituisse. mainloop() sta bloccando, quindi la password non verrà restituita finché la finestra non viene distrutta da onokclick() o onpwdentry() – pycoder112358

+0

Grazie, corretto l'ultimo bug, che stava modificando la password al di fuori del suo ambito, il che significava che il metodo stava ancora tornando "". Aggiunto un hack non locale per Python 2.x (usando dict), e funziona con successo! – liamzebedee

12

Perché hai chiesto per la semplice (Python 2.7):

import Tkinter, tkSimpleDialog 
tkSimpleDialog.askstring("Password", "Enter password:", show='*') 

Per Python 3.3:

import tkinter 
tkinter.simpledialog.askstring("Password", "Enter password:", show='*') 
+0

Questo dovrebbe ottenere più voti. – palsch

+0

Puoi dire come farlo funzionare in Pyhton 3.x? – Vasily

+0

Per Python 3.3: import tkinter tkinter.simpledialog.askstring ("Password", "Immetti password:", mostra = '*') – ryry1985

3

Perché non tutti vogliono usare TK, ecco uno script utilizzando PyQt:

from PyQt5.QtWidgets import QApplication, QInputDialog, QLineEdit 
import sys 
app = QApplication(sys.argv) 
qd = QInputDialog() 
qd.setTextEchoMode(QLineEdit.Password) 
qd.show() 
app.exec() 

E, perché non sarebbe di solito basta chiedere ad un utente una password solo per il gusto di farlo:

#!/bin/env python3 
#passwordPrompt.py 

from PyQt5.QtWidgets import QApplication, QInputDialog 
import sys, time 

def succFunc(): 
    sys.stdout.write(qd.textValue()) 
    sys.stdout.flush() 
    exit(0) 

def failFunc(): 
    exit(1) 

app = QApplication(sys.argv) 
qd = QInputDialog() 
#QLineEdit.Password 
qd.setTextEchoMode(2) 
qd.rejected.connect(failFunc) 
qd.accepted.connect(succFunc) 
qd.show() 
app.exec() 

e la corrispondente funzione di bash:

#!/bin/bash 

passwordPrompt.py | tee 
2

risolti i problemi di scoping di @ pycoder112358 posta:

from tkinter import * 

PASSWORD = '' 

def get_passwd(): 
    global PASSWORD 
    root = Tk() 
    pwdbox = Entry(root, show = '*') 

    def onpwdentry(evt): 
     global PASSWORD 
     PASSWORD = pwdbox.get() 
     root.destroy() 
    def onokclick():  
     global PASSWORD 
     PASSWORD = pwdbox.get() 
     root.destroy() 

    Label(root, text = 'Password').pack(side = 'top') 

    pwdbox.pack(side = 'top') 
    pwdbox.bind('<Return>', onpwdentry) 
    Button(root, command=onokclick, text = 'OK').pack(side = 'top') 

    root.mainloop() 
    return PASSWORD 
1

Ampliando la risposta di Diego con un po 'di pulizia minima (senza questo mi è stato sempre crash bizzeffe cercando di usare la sua splendidamente breve esempio):

import Tkinter, tkSimpleDialog 
root = Tkinter.Tk() # dialog needs a root window, or will create an "ugly" one for you 
root.withdraw() # hide the root window 
password = tkSimpleDialog.askstring("Password", "Enter password:", show='*', parent=root) 
root.destroy() # clean up after yourself! 

Questo funzionerà bene da un programma che altrimenti è solo un'applicazione terminale/console.

+0

Per me questa è la soluzione migliore dal momento che sto avendo un'applicazione console. Ma come aprire la finestra di dialogo sullo schermo principale, quando si hanno più schermi su Linux? La soluzione da @ pycoder112358 apre la finestra di dialogo sulla schermata principale. – eztam