123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- #!/usr/bin/env python3
- import configparser
- import sys
- import tkinter as tk
- import tkinter.messagebox
- from tkinter.constants import NSEW
- import threading
- import os
- import socket
- import selectors
- import json
- from functools import partial
- config_fname = "config.txt"
- sel = selectors.DefaultSelector()
- messages = [b"Message 1 from client.", b"Message 2 from client."]
- class Client(threading.Thread):
- def __init__(self, host, port, username, gui):
- super().__init__()
- self.host = host
- self.port = port
- self.sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
- self.name = username
- self.gui = gui
- self.start()
- def start(self):
- self.sock.connect((self.host, self.port))
- print('Connected to {}:{}'.format(self.host, self.port))
- # Send the username as a welcome message
- self.sock.sendall(self.name.encode('utf8'))
- super().start()
- def close(self):
- try:
- self.sock.close()
- except:
- pass
- def send(self, message):
- self.sock.sendall(message.encode('utf8'))
- def vote(self, player):
- self.sock.sendall(str(player).encode('utf8'))
- def run(self):
- try:
- while True:
- message = self.sock.recv(4096).decode('utf8')
- if message:
- data = json.loads(message)
- if "playerid" in data:
- self.gui.player_id = int(data["playerid"])
- self.gui.server_data = data
- if data["state"] == "vote":
- self.gui.messages = []
- for key in data["messages"]:
- self.gui.messages.append((key, data["messages"][key]))
- self.gui.switch_to(data["state"])
- else:
- self.close()
- except:
- self.close()
- class GUI(tk.Frame):
- def __init__(self, master=None):
- self.config= configparser.ConfigParser()
- self.config.read(config_fname, "UTF8")
- tk.Frame.__init__(self, master)
- self.parent=master
- self.parent.protocol("WM_DELETE_WINDOW", self.quit)
- domyslne=self.config["DEFAULT"]
- self.geometria_baza=domyslne.get('bazowa_geometria',"1000x800+50+50")
- self.parent.geometry(self.geometria_baza)
- self.parent.minsize(1024, 768)
- self.utworz_bazowe_menu()
- # self.utworz_pasek_narzedzi()
- self.utworz_status()
- self.dodaj_menu_custom()
- self.dodaj_menu_help()
- # self.utworz_dodatki()
- self.parent.columnconfigure(0, weight=999)
- self.parent.columnconfigure(1, weight=1)
- self.parent.rowconfigure(0, weight=1)
- self.parent.rowconfigure(1, weight=9999)
- self.parent.rowconfigure(2, weight=1)
- self.client = None
- self.bg_color = '#36393f'
- self.font_color = '#cccccc'
- self.frames = {}
- self.frames["wait"] = self.draw_wait_screen()
- self.frames["game"] = self.draw_game_screen()
- self.frames["welcome"] = self.draw_welcome_screen()
- self.switch_to("welcome")
- self.messages = []
- self.player_id = -1
- self.server_data = {}
- self.master.title("AFORYZMY")
- def utworz_pasek_narzedzi(self):
- self.toolbar_images = [] #muszą być pamiętane stale
- self.toolbar = tk.Frame(self.parent)
- for image, command in (
- ("res/filenew.gif", self.file_new),
- ("res/fileopen.gif", self.file_open),
- ("res/filesave.gif", self.file_save)):
- image = os.path.join(os.path.dirname(__file__), image)
- try:
- image = tkinter.PhotoImage(file=image)
- self.toolbar_images.append(image)
- button = tkinter.Button(self.toolbar, image=image,
- command=command)
- button.grid(row=0, column=len(self.toolbar_images) -1) #KOLEJNE ELEMENTY
- except tkinter.TclError as err:
- print(err) # gdy kłopoty z odczytaniem pliku
- self.toolbar.grid(row=0, column=0, columnspan=2, sticky=tkinter.NSEW)
-
-
- def utworz_dodatki(self):
- pass
-
- def utworz_status(self):
- self.statusbar = tk.Label(self.parent, text="Status...",
- anchor=tkinter.W)
- self.statusbar.after(5000, self.clearStatusBar)
- self.statusbar.grid(row=2, column=0, columnspan=2,
- sticky=tkinter.EW)
- pass
-
- def ustawStatusBar(self, txt):
- self.statusbar["text"] = txt
-
- def clearStatusBar(self):
- self.statusbar["text"] = ""
-
- def utworz_bazowe_menu(self):
- self.menubar = tk.Menu(self.parent)
- self.parent["menu"] = self.menubar
- fileMenu = tk.Menu(self.menubar)
- for label, command, shortcut_text, shortcut in (
- ("Rozłącz", self.disconnect, None, None),
- ("Quit", self.quit, "Ctrl+Q", "<Control-q>")):
- if label is None:
- fileMenu.add_separator()
- else:
- fileMenu.add_command(label=label, underline=0,
- command=command, accelerator=shortcut_text)
- self.parent.bind(shortcut, command)
- self.menubar.add_cascade(label="File", menu=fileMenu, underline=0)
- pass
-
- def dodaj_menu_help(self):
- fileMenu = tk.Menu(self.menubar)
- fileMenu.add_command(label="About...", underline=0,
- command=self.file_new, accelerator="Ctrl+B")
- self.parent.bind("<Control-b>", self.file_new)
- self.menubar.add_cascade(label="Help", menu=fileMenu, underline=0)
- pass
- def close(self):
- geometria = self.parent.winfo_geometry()
- self.config["DEFAULT"]["bazowa_geometria"] = geometria
- with open(config_fname, 'w') as config_plik:
- self.config.write(config_plik)
- self.parent.destroy()
- def disconnect(self, event= None):
- if self.client is not None:
- self.client.close()
- self.client = None
- self.switch_to("welcome")
- def quit(self, event= None):
- reply = tkinter.messagebox.askyesno(
- "Wyjście",
- "Naprawdę wyjść?", parent=self.parent)
- event=event
- if reply:
- if (self.client is not None):
- self.client.close()
- self.close()
-
- def dodaj_menu_custom(self):
- pass
- def file_new(self, event=None):
- event=event
- def file_open(self,event=None):
- event=event
- pass
- def file_save(self,event=None):
- event=event
- pass
- def connect(self):
- self.client = Client(self.address_entry.get(), 7312, self.username_entry.get(), self)
- def upload(self):
- self.switch_to("wait")
- self.client.send(self.aphorism_entry.get())
- def vote(self, player):
- self.switch_to("wait")
- self.client.vote(player)
- def switch_to(self, state):
- for frame in self.frames:
- self.frames[frame].grid_forget()
- if state == "vote" or state == "display":
- self.frames[state] = self.draw_screen(state)
- self.frames[state].grid(row=1, column=0, columnspan=1, rowspan=1, sticky=NSEW)
- def draw_wait_screen(self):
- frame = tk.Frame(self.parent, background=self.bg_color)
- label = tk.Label(frame, text="Waiting for other players", pady=100, bg=self.bg_color, fg=self.font_color)
- label.pack()
- return frame
- def draw_screen(self, type):
- if(type == "vote"):
- frame = tk.Frame(self.parent, background=self.bg_color)
- title_label = tk.Label(frame, text="AFORYZMY", bg=self.bg_color, fg=self.font_color, font="Helvetica 22")
- title_label.pack()
- tk.Label(frame, text="Wybierz najlepszą definicję ASS", fg=self.font_color, bg=self.bg_color, font="Helvetica 12", height="2", anchor="n").pack()
- for message in self.messages:
- player, text = message
- if str(player) != str(self.player_id):
- tk.Button(frame, text=text, fg=self.font_color, bg=self.bg_color, font="Helvetica 12", width="80", height="3", pady="2", relief="flat", command=partial(self.vote, player)).pack()
- return frame
- if (type == "display"):
- frame = tk.Frame(self.parent, background=self.bg_color)
- title_label = tk.Label(frame, text="AFORYZMY", bg=self.bg_color, fg=self.font_color, font="Helvetica 22")
- title_label.pack()
- tk.Label(frame, text="Wyniki", fg=self.font_color, bg=self.bg_color,
- font="Helvetica 12", height="2", anchor="n").pack()
- for message in self.messages:
- player, text = message
- total_score = 0
- score = 0
- if player in self.server_data["total_scores"]:
- total_score = self.server_data["total_scores"][player]
- if player in self.server_data["scores"]:
- score = self.server_data["scores"][player]
- tk.Label(frame, text="{} ({}):\n{} ({})".format(self.server_data["users"][player], total_score, text, score), fg=self.font_color, bg=self.bg_color, font="Helvetica 12", width="100", anchor="nw",
- height="3", pady="2").pack()
- tk.Label(frame, text="Kolejna runda rozpocznie się za chwilę", fg=self.font_color, bg=self.bg_color,
- font="Helvetica 12", height="3", anchor="s").pack()
- return frame
- def draw_game_screen(self):
- frame = tk.Frame(self.parent, background=self.bg_color)
- title_label = tk.Label(frame, text="AFORYZMY", bg=self.bg_color, fg=self.font_color, font="Helvetica 22")
- title_label.pack()
- tk.Label(frame, text="Describe the word: ASS", fg=self.font_color, bg=self.bg_color, font="Helvetica 12").pack()
- sv = tk.StringVar()
- self.aphorism_entry = tk.Entry(frame, width=80, textvariable=sv)
- sv.trace_add("write", lambda x, y, z: self.key_fix(sv, 100))
- self.aphorism_entry.pack()
- send_button = tk.Button(frame, text="Send", command=self.upload)
- send_button.pack()
- return frame
-
- def draw_welcome_screen(self):
- frame = tk.Frame(self.parent, background=self.bg_color)
- title_label = tk.Label(frame, text="AFORYZMY", bg=self.bg_color, fg=self.font_color, font="Helvetica 22")
- title_label.pack()
- tk.Label(frame, text="Login", fg=self.font_color, bg=self.bg_color, font="Helvetica 12").pack()
- sv = tk.StringVar()
- self.username_entry = tk.Entry(frame, textvariable=sv)
- sv.trace_add("write", lambda x,y,z: self.key_fix(sv, 20))
- self.username_entry.pack()
- tk.Label(frame, text="Address", fg=self.font_color, bg=self.bg_color, font="Helvetica 12").pack()
- self.address_entry = tk.Entry(frame)
- self.address_entry.insert(0,"localhost")
- self.address_entry.pack()
- title_button = tk.Button(frame, text="Connect", command=self.connect)
- title_button.pack()
- return frame
- def key_fix(self, sv, limit):
- str = sv.get()
- list = [
- ('ę', 'ê'), ('Ę', 'Ê'),
- ('ś', 'œ'), ('Ś', 'Œ'),
- ('ć', 'æ'), ('Ć', 'Æ'),
- ('ł', '³'), ('Ł', '£'),
- ('ń', 'ñ'), ('Ń', 'Ñ'),
- ('ą', '¹'), ('Ą', '¥'),
- ('ż', '¿'), ('Ż', '¯'),
- ('ź', 'Ÿ'), #('Ź', '')
- ]
- for (pl, k) in list:
- str = str.replace(k, pl)
- sv.set(str[:limit])
-
- if __name__ == '__main__':
- root = tk.Tk()
- app = GUI(master=root)
- app.mainloop()
- pass
|