Login Generator with MVC -> finish
This commit is contained in:
parent
7a88f6a139
commit
021a26838c
|
@ -3415,71 +3415,68 @@ The overhead is quite large but it makes the code a lot more scalable.
|
||||||
|
|
||||||
```python
|
```python
|
||||||
from tkinter import *
|
from tkinter import *
|
||||||
|
from tkinter import ttk
|
||||||
import login_generator
|
import login_generator
|
||||||
import time
|
import time
|
||||||
import threading
|
import threading
|
||||||
import queue
|
import queue
|
||||||
|
|
||||||
|
|
||||||
class View(wx.Dialog):
|
class View(Frame):
|
||||||
def __init__(self, controller):
|
def __init__(self, controller):
|
||||||
wx.Dialog.__init__(self, None, title="Login Generator")
|
Frame.__init__(self)
|
||||||
self.controller = controller
|
self.controller = controller
|
||||||
self.full_window = wx.Panel(self)
|
self.full_window = PanedWindow(self, orient=VERTICAL)
|
||||||
self.full_window_sizer = wx.BoxSizer(wx.VERTICAL)
|
self.full_window.pack(fill=BOTH, expand=True)
|
||||||
self.full_window_sizer.Add(self.create_top_panel(), 0, wx.EXPAND | wx.ALL, 20)
|
self.create_top_panel()
|
||||||
self.full_window_sizer.Add(self.create_bottom_panel(), 0, wx.EXPAND, 0)
|
self.create_bottom_panel()
|
||||||
self.full_window.SetSizer(self.full_window_sizer)
|
self.pack(fill=BOTH, expand=True)
|
||||||
self.Show()
|
|
||||||
|
|
||||||
def create_bottom_panel(self):
|
def create_bottom_panel(self):
|
||||||
bottom_panel = wx.Panel(self.full_window)
|
bottom_panel = PanedWindow(self.full_window, bg="green")
|
||||||
bottom_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
bottom_panel.pack(fill=BOTH, side=BOTTOM)
|
||||||
self.login_list = wx.ListCtrl(bottom_panel, style=wx.LC_REPORT)
|
# List
|
||||||
self.login_list.Bind(wx.EVT_RIGHT_UP, self.show_popup)
|
self.login_list = ttk.Treeview(bottom_panel, columns=["username", "password"], show="headings", height=6)
|
||||||
self.login_list.InsertColumn(0, 'username', width=200)
|
self.login_list.pack()
|
||||||
self.login_list.InsertColumn(1, 'password', width=200)
|
self.login_list.heading("username", text="Username")
|
||||||
bottom_panel_sizer.Add(self.login_list, 0, wx.EXPAND | wx.ALL, 200)
|
self.login_list.heading("password", text="Password")
|
||||||
return bottom_panel
|
self.login_list.bind("<ButtonRelease-1>", lambda e: self.show_popup())
|
||||||
|
|
||||||
def create_top_panel(self):
|
def create_top_panel(self):
|
||||||
top_panel = wx.Panel(self.full_window)
|
top_panel = PanedWindow(self.full_window, bg="red")
|
||||||
top_panel_sizer = wx.BoxSizer(wx.HORIZONTAL)
|
self.login_amount = Text(top_panel, height=5, width=52)
|
||||||
self.login_amount = wx.TextCtrl(top_panel)
|
self.login_amount.place(x=10, y=10)
|
||||||
self.login_complex = wx.CheckBox(top_panel, label="complex")
|
self.complex = BooleanVar()
|
||||||
self.login_create = wx.Button(top_panel, label="Create")
|
self.complex.set(False)
|
||||||
self.login_create.Bind(wx.EVT_BUTTON, self.submit_request)
|
self.login_complex = Checkbutton(top_panel, text="complex", var=self.complex)
|
||||||
top_panel_sizer.Add(self.login_amount, 1, wx.EXPAND|wx.ALL,0)
|
self.login_complex.place(x=10, y=100)
|
||||||
top_panel_sizer.Add(self.login_complex, 1, wx.EXPAND|wx.ALL,0)
|
self.login_create = Button(top_panel, text="Create", command=lambda: self.submit_request())
|
||||||
top_panel_sizer.Add(self.login_create, 1, wx.EXPAND|wx.ALL,0)
|
self.login_create.place(x=100, y=100)
|
||||||
top_panel.SetSizer(top_panel_sizer)
|
top_panel.pack(expand=True, fill=BOTH)
|
||||||
return top_panel
|
|
||||||
|
|
||||||
def show_popup(self, event):
|
|
||||||
menu = wx.Menu()
|
|
||||||
menu.Append(1, "Copy selected items")
|
|
||||||
menu.Bind(wx.EVT_MENU, self.copy_items, id=1)
|
|
||||||
self.PopupMenu(menu)
|
|
||||||
|
|
||||||
def copy_items(self, event):
|
def show_popup(self):
|
||||||
selected_items = []
|
global app
|
||||||
for i in range(self.login_list.GetItemCount()):
|
menu = Menu()
|
||||||
if self.login_list.IsSelected(i):
|
menu.add_command(label="Copy selected items", command=lambda : self.copy_items())
|
||||||
username = selected_items.append(
|
app.config(menu=menu)
|
||||||
self.login_list.GetItem(i, 0).GetText()
|
|
||||||
)
|
|
||||||
password = selected_items.append(
|
|
||||||
self.login_list.GetItem(i, 1).GetText()
|
|
||||||
)
|
|
||||||
clipdata = wx.TextDataObject()
|
|
||||||
clipdata.SetText("\n".join(selected_items))
|
|
||||||
wx.TheClipboard.Open()
|
|
||||||
wx.TheClipboard.SetData(clipdata)
|
|
||||||
wx.TheClipboard.Close()
|
|
||||||
|
|
||||||
def submit_request(self, event):
|
def copy_items(self):
|
||||||
amount = self.login_amount.GetValue()
|
try:
|
||||||
complex_bool = self.login_complex.GetValue()
|
Item = self.login_list.item(self.login_list.focus())
|
||||||
|
FunctionValue = Item.values()
|
||||||
|
Array = list(FunctionValue)
|
||||||
|
Login = Array[2]
|
||||||
|
self.login_amount.insert(END, "Username : {} \nPassword : {} \n".format(Login[0], Login[1]))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
except:
|
||||||
|
Msg = Toplevel(root)
|
||||||
|
l1 = Label(Msg, text="You have to take something")
|
||||||
|
l1.pack(fill=BOTH, expand=True)
|
||||||
|
|
||||||
|
def submit_request(self):
|
||||||
|
amount = self.login_amount.get("1.0", END)
|
||||||
|
complex_bool = self.complex.get()
|
||||||
try:
|
try:
|
||||||
amount = int(amount)
|
amount = int(amount)
|
||||||
except:
|
except:
|
||||||
|
@ -3488,13 +3485,13 @@ class View(wx.Dialog):
|
||||||
|
|
||||||
def update_logins(self, login):
|
def update_logins(self, login):
|
||||||
username, password = login
|
username, password = login
|
||||||
index = self.login_list.InsertItem(0, username)
|
self.login_list.insert('', END, values=[username, password])
|
||||||
self.login_list.SetItem(index, 1, password)
|
|
||||||
|
|
||||||
|
|
||||||
class Controller(object):
|
class Controller(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.app = wx.App()
|
global app
|
||||||
|
app.title("Login Generator")
|
||||||
|
app.geometry("450x300")
|
||||||
self.view = View(self)
|
self.view = View(self)
|
||||||
self.model = Model(self)
|
self.model = Model(self)
|
||||||
|
|
||||||
|
@ -3503,7 +3500,7 @@ class Controller(object):
|
||||||
|
|
||||||
def set_new_logins(self, logins):
|
def set_new_logins(self, logins):
|
||||||
self.view.update_logins(logins)
|
self.view.update_logins(logins)
|
||||||
|
|
||||||
|
|
||||||
class Model(threading.Thread):
|
class Model(threading.Thread):
|
||||||
def __init__(self, controller):
|
def __init__(self, controller):
|
||||||
|
@ -3524,13 +3521,140 @@ class Model(threading.Thread):
|
||||||
def generate_login(self, amount, complex_bool):
|
def generate_login(self, amount, complex_bool):
|
||||||
for i in range(0, amount):
|
for i in range(0, amount):
|
||||||
self.queue.put((amount, complex_bool))
|
self.queue.put((amount, complex_bool))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
|
app = Tk()
|
||||||
mvc = Controller()
|
mvc = Controller()
|
||||||
mvc.app.MainLoop()
|
app.mainloop()
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
|
If you want to add a scrollbar in the project.
|
||||||
|
|
||||||
|
````python
|
||||||
|
from tkinter import *
|
||||||
|
from tkinter import ttk
|
||||||
|
import login_generator
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import queue
|
||||||
|
|
||||||
|
|
||||||
|
class View(Frame):
|
||||||
|
def __init__(self, controller):
|
||||||
|
Frame.__init__(self)
|
||||||
|
self.controller = controller
|
||||||
|
self.full_window = PanedWindow(self, orient=VERTICAL)
|
||||||
|
self.full_window.pack(fill=BOTH, expand=True)
|
||||||
|
self.create_top_panel()
|
||||||
|
self.create_bottom_panel()
|
||||||
|
self.pack(fill=BOTH, expand=True)
|
||||||
|
|
||||||
|
def create_bottom_panel(self):
|
||||||
|
bottom_panel = PanedWindow(self.full_window, bg="green")
|
||||||
|
bottom_panel.pack(fill=BOTH, side=BOTTOM)
|
||||||
|
##Scrollbar
|
||||||
|
self.Scrollbar = Scrollbar(bottom_panel )
|
||||||
|
self.Scrollbar.pack(side=RIGHT, fill= Y)
|
||||||
|
# List
|
||||||
|
self.login_list = ttk.Treeview(bottom_panel, columns=["username", "password"], show="headings", height=6, yscrollcommand= self.Scrollbar.set)
|
||||||
|
self.login_list.pack()
|
||||||
|
self.login_list.heading("username", text="Username")
|
||||||
|
self.login_list.heading("password", text="Password")
|
||||||
|
self.login_list.bind("<ButtonRelease-1>", lambda e: self.show_popup())
|
||||||
|
self.Scrollbar.config(command= self.login_list.yview)
|
||||||
|
|
||||||
|
|
||||||
|
def create_top_panel(self):
|
||||||
|
top_panel = PanedWindow(self.full_window, bg="red")
|
||||||
|
self.login_amount = Text(top_panel, height=5, width=52)
|
||||||
|
self.login_amount.place(x=10, y=10)
|
||||||
|
self.complex = BooleanVar()
|
||||||
|
self.complex.set(False)
|
||||||
|
self.login_complex = Checkbutton(top_panel, text="complex", var=self.complex)
|
||||||
|
self.login_complex.place(x=10, y=100)
|
||||||
|
self.login_create = Button(top_panel, text="Create", command=lambda: self.submit_request())
|
||||||
|
self.login_create.place(x=100, y=100)
|
||||||
|
top_panel.pack(expand=True, fill=BOTH)
|
||||||
|
|
||||||
|
def show_popup(self):
|
||||||
|
global app
|
||||||
|
menu = Menu()
|
||||||
|
menu.add_command(label="Copy selected items", command=lambda : self.copy_items())
|
||||||
|
app.config(menu=menu)
|
||||||
|
|
||||||
|
def copy_items(self):
|
||||||
|
try:
|
||||||
|
Item = self.login_list.item(self.login_list.focus())
|
||||||
|
FunctionValue = Item.values()
|
||||||
|
Array = list(FunctionValue)
|
||||||
|
Login = Array[2]
|
||||||
|
self.login_amount.insert(END, "Username : {} \nPassword : {} \n".format(Login[0], Login[1]))
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
except:
|
||||||
|
Msg = Toplevel(root)
|
||||||
|
l1 = Label(Msg, text="You have to take something")
|
||||||
|
l1.pack(fill=BOTH, expand=True)
|
||||||
|
|
||||||
|
def submit_request(self):
|
||||||
|
amount = self.login_amount.get("1.0", END)
|
||||||
|
complex_bool = self.complex.get()
|
||||||
|
try:
|
||||||
|
amount = int(amount)
|
||||||
|
except:
|
||||||
|
amount = 1
|
||||||
|
self.controller.get_new_logins(amount, complex_bool)
|
||||||
|
|
||||||
|
def update_logins(self, login):
|
||||||
|
username, password = login
|
||||||
|
self.login_list.insert('', END, values=[username, password])
|
||||||
|
|
||||||
|
class Controller(object):
|
||||||
|
def __init__(self):
|
||||||
|
global app
|
||||||
|
app.title("Login Generator")
|
||||||
|
app.geometry("450x300")
|
||||||
|
self.view = View(self)
|
||||||
|
self.model = Model(self)
|
||||||
|
|
||||||
|
def get_new_logins(self, amount, complex_bool):
|
||||||
|
self.model.generate_login(amount, complex_bool)
|
||||||
|
|
||||||
|
def set_new_logins(self, logins):
|
||||||
|
self.view.update_logins(logins)
|
||||||
|
|
||||||
|
|
||||||
|
class Model(threading.Thread):
|
||||||
|
def __init__(self, controller):
|
||||||
|
threading.Thread.__init__(self, target=self.main)
|
||||||
|
self.controller = controller
|
||||||
|
self.queue = queue.Queue()
|
||||||
|
self.start()
|
||||||
|
|
||||||
|
def main(self):
|
||||||
|
while True:
|
||||||
|
amount, complex_bool = self.queue.get()
|
||||||
|
username = login_generator.generate_username()
|
||||||
|
password = login_generator.generate_password(12, complex_bool)
|
||||||
|
logins = (username, password)
|
||||||
|
self.controller.set_new_logins(logins)
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
def generate_login(self, amount, complex_bool):
|
||||||
|
for i in range(0, amount):
|
||||||
|
self.queue.put((amount, complex_bool))
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
app = Tk()
|
||||||
|
mvc = Controller()
|
||||||
|
app.mainloop()
|
||||||
|
````
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# Coding challenge - Login generator with GUI
|
# Coding challenge - Login generator with GUI
|
||||||
|
|
||||||
# Coding challenge - Trivial pursuit with GUI
|
# Coding challenge - Trivial pursuit with GUI
|
||||||
|
|
|
@ -100,8 +100,8 @@ This repository contains some notes and exercises for learning python3.
|
||||||
* Threading
|
* Threading
|
||||||
* Day 9
|
* Day 9
|
||||||
* GUI programming
|
* GUI programming
|
||||||
* wxpython helloworld
|
* Tkinter helloworld
|
||||||
* wxpython guess the number
|
* Tkinter guess the number
|
||||||
* MVC design pattern
|
* MVC design pattern
|
||||||
* Day 10-12
|
* Day 10-12
|
||||||
* Coding challenge - Login generator with GUI
|
* Coding challenge - Login generator with GUI
|
||||||
|
|
Loading…
Reference in New Issue