I am building a GUI that requires me to log on to a remote computer via ssh. I am using paramiko to do this.
What I want to achieve is that a log in window is showed when the application is launched. The user has to put in some credentials. If the login is successful, then display the main window of the application. If the login fails, then remain at the login window.
If login succeeds, I want the ssh_client object to be passed on to the MainWindow class, so that the established connection can be used to perform tasks on the remote computer. However, how can I pass the ssh_client object to MainWindow?
The following code runs, but makes no attempt to use the established ssh_client. What could I do to be able to use the ssh_client from Login in MainWindow?
Perhaps I should just reestablish the connection in MainWindow - bu then I need to pass the credentials to MainWindow, which seems like the same kind of problem I am having right now.
import Tkinter as tk
import paramiko
import time
class Application(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
container = tk.Frame(self)
container.grid(row=0, column=0, sticky="nsew")
container.grid_rowconfigure(0, weight=1)
container.grid_columnconfigure(0, weight=1)
self.frames = {}
for F in (Login, MainWindow):
frame = F(container, self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(Login)
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()
class Login(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.ssh_client = paramiko.SSHClient()
self.ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
self.parent = parent
self.controller = controller
self.grid(row=0, column=0)
self.user = tk.StringVar()
self.user.set("my_username") # Default user
self.host_options = ["host1", "host2"]
self.host = tk.StringVar()
self.host.set(self.host_options[0]) # Default hostname
l_user = tk.Label(self, text="Username: ")
l_user.grid(row=0, column=0, sticky=tk.E)
self.entry_user = tk.Entry(self)
self.entry_user.grid(row=0, column=1, sticky=tk.W)
self.entry_user.insert(0, self.user.get())
l_pwd = tk.Label(self, text="Password: ")
l_pwd.grid(row=1, column=0, sticky=tk.E)
self.entry_pwd = tk.Entry(self, show="*")
self.entry_pwd.grid(row=1, column=1, sticky=tk.W)
l_host = tk.Label(self, text="Hostname: ")
l_host.grid(row=2, column=0, sticky=tk.E)
optionmenu_host = tk.OptionMenu(self, self.host, *self.host_options)
optionmenu_host.grid(row=2, column=1, sticky=tk.W)
b_login = tk.Button(self, text="Log in", command=self.authorize)
b_login.grid(row=3, column=0, sticky=tk.W)
b_quit = tk.Button(self, text="Quit", command=self.parent.destroy)
b_quit.grid(row=4, column=0, sticky=tk.W)
def authorize(self):
try:
self.ssh_client.connect(hostname=self.host.get(), username=self.entry_user.get(), password=self.entry_pwd.get())
self.controller.show_frame(MainWindow)
except paramiko.AuthenticationException:
l_error = tk.Label(self, text="Login failed...", fg="red")
l_error.grid(row=4, column=1, sticky=tk.W)
l_error.after(2000, l_error.destroy)
class MainWindow(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.grid(row=0, column=0)
l = tk.Label(self, text="Log in was successful!")
l.grid(row=0, column=0, sticky=tk.W)
###################################
# run application
if __name__ == "__main__":
app = Application()
app.mainloop()
###################################
Here's what I mean, plus a few other improvements:
self.master = master
automatically, so you don't need that line.I can't test this so let me know how it works.