2013-03-30 17 views
5

Zajmuję się tworzeniem demona kopii zapasowej, który będzie działał dyskretnie w tle. Demon bazuje na kopii zapasowej duplicity, która podczas tworzenia kopii zapasowej wymaga klucza szyfrowania. Nie mogę poprosić o hasło za pośrednictwem konsoli, ponieważ oczywiście demon nie ma do niego dostępu.Najprostsza metoda pytania użytkownika o hasło za pomocą graficznego okna dialogowego w Pythonie?

Jak mogę łatwo utworzyć monit, który prosi użytkownika o wpisanie hasła i zwraca go do aplikacji (za pomocą zmiennej Python)? Używam Python 2.7.

+0

Czy można używać TkInter lub PyQt? – chrisaycock

+0

Tak, nie martwię się zbytnio o dodatkowe zależności. – liamzebedee

Odpowiedz

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

Nie działa dla mnie. Rozwiązałem problem z odwołaniem roota przed zdefiniowaniem. Teraz mogę wyświetlić okno dialogowe, ale kiedy wpisuję hasło 1) ** znaki pokazują, zamiast czarnych kropek ** i 2), kiedy uderzę return ** nic nie jest zwracane z 'getpwd' **. Ponadto pojawia się błąd po kliknięciu przycisku OK - onpwdentry() przyjmuje dokładnie jeden argument Dzięki za szybką odpowiedź. – liamzebedee

+0

Ok, ta ostatnia edycja powinna naprawić twoje problemy. Dla 1) ustawiam właściwość "show" widżetu Entry na "*", aby wyświetlała się gwiazdka zamiast liter. 2) był niesamowicie głupim błędem z mojej strony: miałem podfunkcje zwracające hasło, kiedy oczywiście chciałem zwrócić główną funkcję. mainloop() jest blokowany, więc hasło nie zostanie zwrócone, dopóki okno nie zostanie zniszczone przez onokclick() lub onpwdentry() – pycoder112358

+0

Dzięki, naprawiliśmy ostatni błąd, który modyfikował hasło poza jego zakresem, co oznaczało, że metoda wciąż wracał "". Dodano nielokalny hack do Pythona 2.x (używając Dicta) i działa poprawnie! – liamzebedee

12

Ponieważ poprosiłeś dla Najprostszym (Python 2.7):

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

dla Pythona 3.3:

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

To powinno uzyskać więcej głosów. – palsch

+0

Czy możesz powiedzieć, jak sprawić, żeby działało w Pyhton 3.x? – Vasily

+0

Dla Pythona 3.3: import tkinter tkinter.simpledialog.askstring ("Hasło", "Wprowadź hasło:", show = '*') – ryry1985

3

Ponieważ nie każdy chce korzystać TK, oto skrypt, za pomocą PyQt:

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

A ponieważ nie będzie zwykle tylko poprosić użytkownika o hasło tylko do cholery go:

#!/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() 

i odpowiadająca funkcji bash:

#!/bin/bash 

passwordPrompt.py | tee 
2

Rozwiązane problemy z scoping @ pycoder112358 post:

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

Rozwijając na odpowiedź Diego z pewnym minimalnym sprzątania (bez tego byłem coraz wywala bród próbuje wykorzystać jego pięknie krótki przykład):

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! 

To będzie działać dobrze z programu, który w przeciwnym razie jest tylko aplikacją terminal/konsola.

+0

Dla mnie jest to najlepsze rozwiązanie, ponieważ mam aplikację konsolową. Ale jak otworzyć okno dialogowe na ekranie głównym, mając wiele ekranów w systemie Linux? Rozwiązanie z @ pycoder112358 otwiera okno dialogowe na ekranie głównym. – eztam

Powiązane problemy