class PrognosisFrame(tkinter.Toplevel): def __init__(self, parent, predictions, years): super().__init__(parent) pred = {} i = 0 for p in predictions: pred[years[i]] = p i += 1 self.df = pd.DataFrame(pred) self.frame = Frame(self, relief=RAISED, borderwidth=1) self.table = Table(self.frame, dataframe=self.df, showtoolbar=True, showstatusbar=True) # График # self.graph = plt.scatter(years, predictions, c='green') self.f = Figure(figsize=(5, 4), dpi=100) self.a = self.f.add_subplot(111) years_str = [str(y) for y in years] self.a.plot(years_str, predictions) # a tk.DrawingArea self.canvas = FigureCanvasTkAgg(self.f, master=self) self.parent = parent self.mycompany = company.Company() self.initUI() self.style = Style() print(self.style.theme_names()) self.style.theme_use('winnative') self.closeButton = Button(self, text="Закрыть", command=self.quit) self.closeButton.pack(side=RIGHT, padx=5, pady=5) def initUI(self): self.title("Fluger Investor 1.00 2021 - Prognosis") self.centerWindow() # Graphics self.canvas.get_tk_widget().pack(side=TOP, fill=BOTH, expand=1) self.canvas._tkcanvas.pack(side=TOP, fill=BOTH, expand=1) # Специальная таблица для DataFrame self.frame.pack(fill=BOTH, expand=True) self.table.show() self.protocol("WM_DELETE_WINDOW", self.on_closing) def on_closing(self): self.destroy() def centerWindow(self): w = 800 h = 600 sw = self.winfo_screenwidth() sh = self.winfo_screenheight() x = (sw - w) / 2 y = (sh - h) / 2 self.geometry('%dx%d+%d+%d' % (w, h, x, y))
class App: def __init__(self, root): self.fr = Frame(root) self.fr.pack(fill='both', expand=1) try: import ttkthemes as ts self.style = ts.themed_style.ThemedStyle() except (NameError, AttributeError): self.style = Style() self._setup_widgets() def _change_theme(self): newtheme = self.theme_val.get() self.style.theme_use(newtheme) def _change_state(self): oldstate = self.but.state() if len(oldstate) > 0: # convert tuple to string oldst = " ".join(str(x) for x in oldstate) self.but.state(['!' + oldst]) newstate = self.state_val.get() self.but.state([newstate]) def _setup_widgets(self): themes = sorted(list(self.style.theme_names())) # Create rasio buttons which will display themes self.theme_val = StringVar() for ix, val in enumerate(themes): themes_rb = Radiobutton(self.fr, value=val, text=val, variable=self.theme_val, command=self._change_theme) themes_rb.grid(column=0, row=ix, padx=5, pady=2, sticky='nw') states = [ 'active', 'alternate', 'background', 'disabled', 'focus', 'invalid', 'pressed', 'readonly', 'selected' ] # Create rasio buttons which will display widget states self.state_val = StringVar() for iy, state in enumerate(states): st_rb = Radiobutton(self.fr, value=state, text=state, variable=self.state_val, command=self._change_state) st_rb.grid(column=1, row=iy, padx=5, pady=5, sticky='nw') # selected widget, if using scrollbar place in own frame self.but = Button(self.fr, text='Button State') self.but.grid(column=0, row=ix + 1, padx=5, pady=5)
class Example(Frame): def __init__(self): super().__init__() self.initUI() def initUI(self): self.master.title("Simple") self.style = Style() # self.style.configure("TFrame", background="#333") print(self.style.theme_names()) # self.style.theme_use("clam") frame = Frame(self, relief=RAISED, borderwidth=1) frame.pack(fill=BOTH, expand=True) self.pack(fill=BOTH, expand=1) self.centerWindow() progButton = Button(self, text="Program") progButton.pack(side=RIGHT) closeButton = Button(self, text="Close") closeButton.pack(side=RIGHT, padx=5, pady=5) okButton = Button(self, text="OK") okButton.pack(side=RIGHT) def centerWindow(self): w = 600 h = 400 sw = self.master.winfo_screenwidth() sh = self.master.winfo_screenheight() x = (sw - w) / 2 y = (sh - h) / 2 self.master.geometry('%dx%d+%d+%d' % (w, h, x, y))
class MainFrame(Tk): def __init__(self): super().__init__() # Create DataFrame self.df = pd.DataFrame({'': ['']}) self.frame = Frame(self, relief=RAISED, borderwidth=1) self.table = Table(self.frame, dataframe=self.df, showtoolbar=True, showstatusbar=True) #self.parent = parent self.mycompany = company.Company() self.initUI() self.style = Style() print(self.style.theme_names()) self.style.theme_use('winnative') self.closeButton = Button(self, text="Закрыть", command=self.quit) self.closeButton.pack(side=RIGHT, padx=5, pady=5) self.loadButton = Button(self, text="Загрузить", command=self.loadCompany) self.loadButton.pack(side=RIGHT) self.modelButton = Button(self, text="Модель", command=self.createModel) self.modelButton.pack(side=RIGHT) self.prognosisButton = Button(self, text="Прогноз", command=self.prognosis) self.prognosisButton.pack(side=RIGHT) self.l1 = Label(self, text='От') self.l2 = Label(self, text='До') self.entry_from = Entry(self, width=4, textvariable=StringVar(self, '2021')) self.entry_to = Entry(self, width=4, textvariable=StringVar(self, '2026')) self.entry_to.pack(side=RIGHT, padx=5) self.l2.pack(side=RIGHT) self.entry_from.pack(side=RIGHT, padx=5) self.l1.pack(side=RIGHT) def initUI(self): self.title("Fluger Investor 1.00 2021") #self.pack(fill=BOTH, expand=1) self.centerWindow() self.frame.pack(fill=BOTH, expand=True) # Специальная таблица для DataFrame self.table.show() #self.pack(fill=BOTH, expand=True) def centerWindow(self): w = 1200 h = 800 sw = self.winfo_screenwidth() sh = self.winfo_screenheight() x = (sw - w) / 2 y = (sh - h) / 2 self.geometry('%dx%d+%d+%d' % (w, h, x, y)) def loadCompany(self): Tk().withdraw( ) # we don't want a full GUI, so keep the root window from appearing # show an "Open" dialog box and return the path to the selected file filename = askopenfilename(initialdir=os.getcwd(), title="Открыть компанию", filetypes=(("json", "*.json"), ("all files", "*.*"))) self.mycompany = company.Company() self.mycompany.load_company_from_file(filename) self.mycompany.load_financials_from_file() self.df = self.mycompany.get_financials() print(self.df) self.table.model.df = self.df self.table.redraw() self.title("Fluger Investor 1.00 2021 - " + self.mycompany.ticker) def createModel(self): modelgen = model_generator.ModelGenerator() modelgen.set_financials(self.mycompany.get_financials()) model, score = modelgen.build_linear_regression_model('Price') self.mycompany.set_price_model(model) messagebox.showinfo("Модель", "Модель создана, score = " + str(score)) def prognosis(self): f = self.entry_from.get() t = self.entry_to.get() years = [i for i in range(int(f), int(t))] fin = self.mycompany.get_financials() fin = fin.drop(["Price"], axis=1) modelgen = model_generator.ModelGenerator() features, predictions = modelgen.predict( self.mycompany.get_price_model(), fin, years) print(features) prognosis_frame.PrognosisFrame(self, predictions, years)
arrowcolor='#A52A2A', # brown focuscolor='#40E0D0' # turquoise ) return maxsize - adj, step root = Tk() style = Style() la0 = Label(root, text="Treeview layout, may change with the theme") la0.pack(pady=5) te = Text(root, bg='#FFFFBB') te.pack(pady=5) la1 = Label(root, text="Select the theme") la1.pack(pady=5) combo = Combobox(root, values=sorted(style.theme_names()), state='readonly') combo.set(style.theme_use()) combo.bind('<<ComboboxSelected>>', lambda _e: theme_changed(combo.get())) combo.pack(pady=5) out = theme_changed(style.theme_use()) te['width'] = out[0] te['height'] = out[1] dataCols = ('Name', 'hash') treeData = (('alice blue', '#F0F8FF'), ('azure', '#F0FFFF'), ('brown4', '#8B2323')) w = Treeview(root, columns=dataCols, show='headings') for col in dataCols: w.heading(col, text=col.title()) w.column(col, width=75) for ix, item in enumerate(treeData):
class NotebookDemo: def __init__(self, fr): self.fr = fr self.style = Style() # ts.ThemedStyle() # Style() self._create_demo_panel() # run this before allBtns self.allBtns = self.ttkbut + self.cbs[1:] + self.rb try: piratz_theme.install('piratz') except Exception: import warnings warnings.warn("piratz theme being used without images") def _create_demo_panel(self): demoPanel = Frame(self.fr, name="demo") demoPanel.pack(side='top', fill='both', expand='y') # create the notebook self.nb = nb = Notebook(demoPanel, name="nb") nb.bind("<<NotebookTabChanged>>", self._on_tab_changed) # extend bindings to top level window allowing # CTRL+TAB - cycles thru tabs # SHIFT+CTRL+TAB - previous tab # ALT+K - select tab using mnemonic (K = underlined letter) nb.enable_traversal() nb.pack(fill='both', expand='y', padx=2, pady=3) self._create_descrip_tab(nb) self._create_treeview_tab(nb) self._create_text_tab(nb) def _create_descrip_tab(self, nb): # frame to hold contents frame = Frame(nb, name='descrip') # widgets to be displayed on 'Description' tab # position and set resize behaviour frame.rowconfigure(1, weight=1) frame.columnconfigure((0, 1), weight=1, uniform=1) lf = LabelFrame(frame, text='Animals') lf.pack(pady=5, padx=5, side='left', fill='y') themes = ['horse', 'elephant', 'crocodile', 'bat', 'grouse'] self.ttkbut = [] for t in themes: b = Button(lf, text=t) b.pack(pady=2) self.ttkbut.append(b) lF2 = LabelFrame(frame, text="Theme Combobox") lF2.pack(pady=5, padx=5) themes = list(sorted( self.style.theme_names())) # get_themes # used in ttkthemes themes.insert(0, "Pick a theme") self.cb = cb = Combobox(lF2, values=themes, state="readonly", height=10) cb.set(themes[0]) #cb.bind('<<ComboboxSelected>>', self.change_style) cb.grid(row=0, column=0, sticky='nw', pady=5) lf1 = LabelFrame(frame, text='Checkbuttons') lf1.pack(pady=5, padx=5, side='left', fill='y') # control variables self.enabled = IntVar() self.cheese = IntVar() self.tomato = IntVar() self.basil = IntVar() self.oregano = IntVar() # checkbuttons self.cbOpt = Checkbutton(lf1, text='Enabled', variable=self.enabled, command=self._toggle_opt) cbCheese = Checkbutton(text='Cheese', variable=self.cheese, command=self._show_vars) cbTomato = Checkbutton(text='Tomato', variable=self.tomato, command=self._show_vars) sep1 = Separator(orient='h') cbBasil = Checkbutton(text='Basil', variable=self.basil, command=self._show_vars) cbOregano = Checkbutton(text='Oregano', variable=self.oregano, command=self._show_vars) sep2 = Separator(orient='h') self.cbs = [ self.cbOpt, sep1, cbCheese, cbTomato, sep2, cbBasil, cbOregano ] for opt in self.cbs: if opt.winfo_class() == 'TCheckbutton': opt.configure(onvalue=1, offvalue=0) opt.setvar(opt.cget('variable'), 0) opt.pack(in_=lf1, side='top', fill='x', pady=2, padx=5, anchor='nw') lf2 = LabelFrame(frame, text='Radiobuttons', labelanchor='n') lf2.pack(pady=5, padx=5, side='left', fill='y') self.rb = [] self.happiness = StringVar() for s in ['Great', 'Good', 'OK', 'Poor', 'Awful']: b = Radiobutton(lf2, text=s, value=s, variable=self.happiness, command=lambda s=s: self._show_vars()) b.pack(anchor='nw', side='top', fill='x', pady=5, padx=5) self.rb.append(b) right = LabelFrame(frame, text='Control Variables') right.pack(pady=5, padx=5, side='left', fill='y') self.vb0 = Label(right, font=('Courier', 10)) self.vb1 = Label(right, font=('Courier', 10)) self.vb2 = Label(right, font=('Courier', 10)) self.vb3 = Label(right, font=('Courier', 10)) self.vb4 = Label(right, font=('Courier', 10)) self.vb5 = Label(right, font=('Courier', 10)) self.vb0.pack(anchor='nw', pady=5, padx=5) self.vb1.pack(anchor='nw', pady=5, padx=5) self.vb2.pack(anchor='nw', pady=5, padx=5) self.vb3.pack(anchor='nw', pady=5, padx=5) self.vb4.pack(anchor='nw', pady=5, padx=5) self.vb5.pack(anchor='nw', pady=5, padx=5) self._show_vars() # add to notebook (underline = index for short-cut character) nb.add(frame, text='Description', underline=0, padding=2) # ============================================================================= def _create_treeview_tab(self, nb): # Populate the second pane. Note that the content doesn't really matter tree = None self.backg = ["white", '#f0f0ff'] tree_columns = ("country", "capital", "currency") tree_data = [("Argentina", "Buenos Aires", "ARS"), ("Australia", "Canberra", "AUD"), ("Brazil", "Brazilia", "BRL"), ("Canada", "Ottawa", "CAD"), ("China", "Beijing", "CNY"), ("France", "Paris", "EUR"), ("Germany", "Berlin", "EUR"), ("India", "New Delhi", "INR"), ("Italy", "Rome", "EUR"), ("Japan", "Tokyo", "JPY"), ("Mexico", "Mexico City", "MXN"), ("Russia", "Moscow", "RUB"), ("South Africa", "Pretoria", "ZAR"), ("United Kingdom", "London", "GBP"), ("United States", "Washington, D.C.", "USD")] container = Frame(nb) container.pack(fill='both', expand=False) self.tree = Treeview(container, columns=tree_columns, show="headings") vsb = Scrollbar(container, orient="vertical", command=self.tree.yview) hsb = Scrollbar(container, orient="horizontal", command=self.tree.xview) self.tree.configure(yscrollcommand=vsb.set, xscrollcommand=hsb.set) self.tree.grid(column=0, row=0, sticky='ns', in_=container) vsb.grid(column=1, row=0, sticky='ns', in_=container) hsb.grid(column=0, row=1, sticky='ew', in_=container) container.grid_columnconfigure(0, weight=1) container.grid_rowconfigure(0, weight=1) for col in tree_columns: self.tree.heading( col, text=col.title(), command=lambda c=col: self.sortby(self.tree, c, 0)) # XXX tkFont.Font().measure expected args are incorrect according # to the Tk docs self.tree.column(col, width=Font().measure(col.title()), stretch=False) for ix, item in enumerate(tree_data): itemID = self.tree.insert('', 'end', values=item) self.tree.item(itemID, tags=itemID) self.tree.tag_configure(itemID, background=self.backg[ix % 2]) # adjust columns lengths if necessary for indx, val in enumerate(item): ilen = Font().measure(val) if self.tree.column(tree_columns[indx], width=None) < ilen: self.tree.column(tree_columns[indx], width=ilen) sg = Sizegrip(container) sg.grid(sticky='e') nb.add(container, text='Treeview', underline=0, padding=2) # ============================================================================= def _create_text_tab(self, nb): self.dir0 = 1 self.dir1 = 1 # populate the third frame with other widgets fr = Frame(nb, name='fr') lF = LabelFrame(fr, text="Slider") fr1 = Frame(lF) fr1.grid(row=0, column=0, sticky='nsew') from_ = 100 to = 0 value = 0 step = 10 fontSize = 9 self.scvar = IntVar() scRange = self.any_number_range(from_, to, step) scLen = len(scRange[1]) * (fontSize + 10) self.sc = Scale(fr1, from_=from_, to=to, variable=self.scvar, orient='vertical', length=scLen, command=self.v_scale) self.sc.set(value) l1 = Label(fr1, textvariable=self.scvar, width=5) l1.grid(row=0, column=0, padx=5, pady=5) self.sc.grid(row=0, column=1, padx=5, pady=5) fr4 = Frame(fr1) fr4.grid(row=0, column=2) sc_split = '\n'.join(scRange[0].split()) lb = Label(fr1, text=sc_split, font=('Courier New', str(fontSize))) lb.grid(row=0, column=2, padx=5, pady=5) fr2 = Frame(lF, name='fr2') fr2.grid(row=0, column=1, sticky='nsew') self.schvar = IntVar() a = 0 b = 100 schRange = self.any_number_range(a, b, s=10) schLen = Font().measure(schRange[0]) self.sch = Scale(fr2, from_=a, to=b, length=schLen, variable=self.schvar, orient='horizontal', command=self.h_scale) self.sch.set(0) l2 = Label(fr2, textvariable=self.schvar) l2.grid(row=1, column=1, pady=2) self.sch.grid(row=2, column=1, padx=5, pady=5, sticky='nsew') l3 = Label(fr2, text=schRange[0], font=('Courier New', str(fontSize))) l3.grid(row=3, column=1, padx=5, pady=5) lF.grid(row=0, column=0, sticky='nesw', pady=5, padx=5) lF1 = LabelFrame(fr, text="Progress", name='lf') pb1var = IntVar() pb2var = IntVar() self.pbar = Progressbar(lF1, variable=pb1var, length=150, mode="indeterminate", name='pb1', orient='horizontal') self.pb2 = Progressbar(lF1, variable=pb2var, length=150, mode='indeterminate', name='pb2', orient='vertical') self.pbar["value"] = 25 self.h_progress() self.v_progress() self.pbar.grid(row=1, column=0, padx=5, pady=5, sticky='nw') self.pb2.grid(row=1, column=1, padx=5, pady=5, sticky='nw') l3 = Label(lF1, textvariable=pb1var) l3.grid(row=0, column=0, pady=2, sticky='nw') l4 = Label(lF1, textvariable=pb2var) l4.grid(row=0, column=1, pady=2, sticky='nw') sg1 = Sizegrip(fr) sg1.grid(row=2, column=2, sticky='e') lF1.grid(row=1, column=0, sticky='nesw', pady=5, padx=5) # add to notebook (underline = index for short-cut character) nb.add(fr, text='Sliders & Others', underline=0) #========================================================================= def _toggle_opt(self): # state of the option buttons controlled # by the state of the Option frame label widget for opt in self.allBtns: if opt.winfo_class() != 'TSeparator': if self.cbOpt.instate(('selected', )): opt['state'] = '!disabled' # enable option self.nb.tab(1, state='normal') else: opt['state'] = 'disabled' self.nb.tab(1, state='disabled') self._show_vars() def _show_vars(self): # set text for labels in var_panel to include the control # variable name and current variable value self.vb0['text'] = '{:<11} {:<8}'.format('enabled:', self.enabled.get()) self.vb1['text'] = '{:<11} {:<8}'.format('cheese:', self.cheese.get()) self.vb2['text'] = '{:<11} {:<8}'.format('tomato:', self.tomato.get()) self.vb3['text'] = '{:<11} {:<8}'.format('basil:', self.basil.get()) self.vb4['text'] = '{:<11} {:<8}'.format('oregano:', self.oregano.get()) self.vb5['text'] = '{:<11} {:<8}'.format('happiness:', self.happiness.get()) def sortby(self, tree, col, descending): """Sort tree contents when a column is clicked on.""" # grab values to sort data = [(tree.set(child, col), child) for child in tree.get_children('')] # reorder data data.sort(reverse=descending) for indx, item in enumerate(data): tree.move(item[1], '', indx) # switch the heading so that it will sort in the opposite direction tree.heading(col, command=lambda col=col: self.sortby( tree, col, int(not descending))) # reconfigure tags after ordering list_of_items = tree.get_children('') for i in range(len(list_of_items)): tree.tag_configure(list_of_items[i], background=self.backg[i % 2]) def any_number_range(self, a, b, s=1): """ Generate consecutive values list between two numbers with optional step (default=1).""" if (a == b): return a else: mx = max(a, b) mn = min(a, b) result = [] output = '' # inclusive upper limit. If not needed, delete '+1' in the line below while (mn < mx + 1): # if step is positive we go from min to max if s > 0: result.append(mn) mn += s # if step is negative we go from max to min if s < 0: result.append(mx) mx += s # val maxLen = 0 output = "" for ix, res in enumerate(result[:-1]): # last value ignored if len(str(res)) > maxLen: maxLen = len(str(res)) if maxLen == 1: output = ' '.join(str(i) for i in result) # converts list to string else: for ix, res in enumerate(result): if maxLen == 2: if len(str(res)) == 1: output = output + str(res) + " " * maxLen elif len(str(res)) == 2: output = output + str(res) + " " else: output = output + str(res) #print(output) return output, result def change_style(self, event=None): """set the Style to the content of the Combobox""" content = self.cb.get() try: self.style.theme_use(content) except TclError as err: messagebox.showerror('Error', err) else: root.title(content) def change_theme(self, theme): window = ttktheme.ThemedTk() window.set_theme(theme) root.title(theme) def _on_tab_changed(self, event): event.widget.update_idletasks() tab = event.widget.nametowidget(event.widget.select()) event.widget.configure(height=tab.winfo_reqheight(), width=tab.winfo_reqwidth()) def h_progress(self): widg = self.pbar widg['value'] += 1 * self.dir0 if widg['value'] == 100: widg.state(['background', '!active']) self.dir0 = -1 widg.after(50, self.h_progress) elif widg['value'] == 0: widg.state(['active', '!background']) self.dir0 = 1 widg.after(50, self.h_progress) else: widg.after(50, self.h_progress) def v_progress(self): widg1 = self.pb2 widg1['value'] += 1 * self.dir1 if widg1['value'] == 0: # (dir1-1)*100+16 widg1.state(['active', '!invalid', '!background']) self.dir1 = 1 widg1.after(40, self.v_progress) elif widg1['value'] == 16: # (dir1-1)*100+16 widg1.state(['background', '!invalid', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 33: widg1.state(['invalid', '!background', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 50: widg1.state(['active', '!invalid', '!background']) widg1.after(40, self.v_progress) elif widg1['value'] == 66: widg1.state(['background', '!invalid', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 83: widg1.state(['invalid', '!background', '!active']) widg1.after(40, self.v_progress) elif widg1['value'] == 100: widg1.state(['active', '!invalid', '!background']) self.dir1 = -1 widg1.after(40, self.v_progress) else: widg1.after(40, self.v_progress) def h_scale(self, schvar): v = int(float(schvar)) widg = self.sch imgw = { 0: ['readonly', '!selected', '!background', '!focus', '!active'], 1: ['selected', '!readonly', '!background', '!focus', '!active'] } if v >= 0 and v < 10: widg.state(['active', '!readonly', '!selected']) elif v > 80 and v < 91: widg.state(['focus', '!background', '!readonly', '!selected']) elif v > 90 and v < 100: widg.state(['background', '!invalid', '!focus']) elif v == 100: widg.state(['invalid', '!background']) else: widg.state(imgw[v % 2]) def v_scale(self, scvar): v = int(float(scvar)) widg1 = self.sc imgw = { 0: ['background', '!selected', '!invalid', '!active'], 1: ['selected', '!invalid', '!background', '!active'] } if v >= 0 and v < 5: widg1.state(['active', '!background', '!selected']) elif v > 90: widg1.state(['invalid', '!selected', '!background']) else: widg1.state(imgw[v % 2])
Preferences.HEIGHT] = Preferences.DEFAULT_WIDTH self.preferences[Preferences.LAYOUT][ Preferences.XOFFSET] = Preferences.DEFAULT_XOFFSET self.preferences[Preferences.LAYOUT][ Preferences.YOFFSET] = Preferences.DEFAULT_YOFFSET self.preferences[Preferences.THEME] = None self.preferences[Preferences.RECENT] = [] preferences = Preferences() root = Tk() root.geometry("1000x500+100+100") style = Style() themes = style.theme_names() def donothing(): filewin = Toplevel(root) button = Button(filewin, text="Do nothing button") button.pack() def ontheme(theme): global style for show_theme in themes: show_themes[show_theme].set(False) show_themes[theme].set(True) print(theme)