def __init__(self, *args, **kwargs): super().__init__(*args, **kwargs) self.timeout = None startbutton = teek.Button(self, "Start", command=self.start) startbutton.pack() cancelbutton = teek.Button(self, "Cancel", command=self.cancel) cancelbutton.pack()
def test_button(capsys): window = teek.Window() stuff = [] button1 = teek.Button(window) button2 = teek.Button(window, 'click me') button3 = teek.Button(window, 'click me', (lambda: stuff.append(3))) assert "text=''" in repr(button1) assert "text='click me'" in repr(button2) assert "text='click me'" in repr(button3) assert button1.config['text'] == '' assert button2.config['text'] == button3.config['text'] == 'click me' for button in [button1, button2, button3]: assert isinstance(button.config['command'], teek.Callback) with pytest.raises(ValueError) as error: button.config['command'] = print assert str(error.value) == ( "cannot set the value of 'command', " "maybe use widget.config['command'].connect() instead?") # ideally there would be some way to click the button virtually and # let tk handle it, but i haven't gotten anything like that to work button1.config['command'].run() button2.config['command'].run() assert stuff == [] button3.config['command'].run() assert stuff == [3] button1.config['command'].connect(stuff.append, args=[1]) button2.config['command'].connect(stuff.append, args=[2]) button3.config['command'].connect(stuff.append, args=['wolo']) button3.config['command'].connect(stuff.append, args=['wolo']) stuff.clear() for button in [button1, button2, button3]: button.config['command'].run() assert stuff == [1, 2, 3, 'wolo', 'wolo'] def oops(): raise ValueError("shit") assert capsys.readouterr() == ('', '') button1.config['command'].connect(oops) button1.config['command'].run() output, errors = capsys.readouterr() assert not output assert "button1.config['command'].connect(oops)" in errors
def test_button_invoke(): button = teek.Button(teek.Window()) stuff = [] button.config['command'].connect(stuff.append, args=[1]) button.config['command'].connect(stuff.append, args=[2]) button.invoke() assert stuff == [1, 2]
def test_state(): assert teek.Menu().state is None assert teek.Toplevel().state is None state = teek.Button(teek.Window()).state assert state is not None assert isinstance(state, collections.abc.Set) assert isinstance(state, collections.abc.MutableSet) assert 'disabled' not in state state.add('disabled') assert 'disabled' in state state.add('disabled') assert 'disabled' in state state.discard('disabled') assert 'disabled' not in state state.discard('disabled') assert 'disabled' not in state state.add('disabled') state.remove('disabled') assert 'disabled' not in state with pytest.raises(KeyError): state.remove('disabled') assert not state assert repr(state) == "<state set: []>" state.add('disabled') assert state assert repr(state) == "<state set: ['disabled']>"
def test_destroy(): window = teek.Window() label = teek.Label(window) frame = teek.Frame(window) button = teek.Button(frame) widgets = [window, label, button] command = teek.create_command(print, str) label.command_list.append(command) assert teek.tcl_call([str], 'info', 'commands', command) == [command] assert window.winfo_children() == [label, frame] assert frame.winfo_children() == [button] for widget in widgets: assert widget.winfo_exists() window.destroy() for widget in widgets: assert not widget.winfo_exists() assert repr(widget).startswith('<destroyed ') assert teek.tcl_call([str], 'info', 'commands', command) == [] with pytest.raises(RuntimeError) as error: label.config['text'] = 'lel' assert str(error.value) == 'the widget has been destroyed'
def test_options(): window = teek.Window() for widget in [teek.Button(window), teek.Label(window)]: assert 'behaves like a dict' in repr(widget.config) assert len(widget.config) == len(list(widget.config)) # abbreviations aren't allowed, it simplifies the implementation # and people aren't aware of abbreviating things in tk anyway assert 'text' in widget.config assert 'tex' not in widget.config with pytest.raises(KeyError): widget.config['tex'] with pytest.raises(TypeError): widget.config.pop('text') # buttons are tested below, this makes sure that windows and # labels don't do something weird when they get an option that # they shouldn't support if not isinstance(widget, teek.Button): with pytest.raises(KeyError): widget.config['command'] = print widget1 = teek.Label(window, 'lol') widget1.config.update({'text': 'asd'}) widget2 = teek.Label(window, text='asd') assert widget1.config == widget2.config widget2.config['text'] = 'tootie' assert widget1.config != widget2.config
def __init__(self, title, text, entry_creator, validator, initial_value, parent): self.validator = validator self.window = teek.Window(title) self.window.on_delete_window.connect(self.on_cancel) if parent is not None: self.window.transient = parent self.var = teek.StringVar() teek.Label(self.window, text).grid(row=0, column=0, columnspan=2) entry = entry_creator(self.window) entry.config['textvariable'] = self.var entry.grid(row=1, column=0, columnspan=2) entry.bind('<Return>', self.on_ok) entry.bind('<Escape>', self.on_cancel) self.ok_button = teek.Button(self.window, "OK", self.on_ok) self.ok_button.grid(row=3, column=0) teek.Button(self.window, "Cancel", self.on_cancel).grid(row=3, column=1) self.window.grid_rows[0].config['weight'] = 1 self.window.grid_rows[2].config['weight'] = 1 for column in self.window.grid_columns: column.config['weight'] = 1 self.result = None self.var.write_trace.connect(self.on_var_changed) self.var.set(initial_value) self.on_var_changed(self.var) # TODO: is this needed? # TODO: add a way to select stuff to teek self.window.geometry(300, 150) entry.focus() teek.tcl_call(None, entry, 'selection', 'range', '0', 'end')
def test_grid(): # grid shares a lot of code with pack, so no need to test everything # separately window = teek.Window() button = teek.Button(window) button.grid(column=1, rowspan=2, sticky='nswe') grid_info = button.grid_info() assert grid_info['column'] == 1 assert grid_info['columnspan'] == 1 assert grid_info['row'] == 0 assert grid_info['rowspan'] == 2 assert grid_info['in'] is button.parent assert grid_info['padx'] == grid_info['pady'] == [teek.ScreenDistance(0)] assert grid_info['ipadx'] == grid_info['ipady'] == teek.ScreenDistance(0) assert grid_info['sticky'] == 'nesw' # not 'nswe' for some reason assert window.grid_slaves() == [button]
def all_widgets(): window = teek.Window() return [ teek.Button(window), teek.Checkbutton(window), teek.Combobox(window), teek.Entry(window), teek.Frame(window), teek.Label(window), teek.LabelFrame(window), teek.Notebook(window), teek.Menu(), teek.Progressbar(window), teek.Scrollbar(window), teek.Separator(window), teek.Spinbox(window), teek.Text(window), teek.Toplevel(), window, ]
def test_place(): window = teek.Window() button = teek.Button(window) button.place(x=123, rely=0.5) place_info = button.place_info() assert place_info['anchor'] == 'nw' assert place_info['bordermode'] == 'inside' assert place_info['in'] is window assert place_info['x'] == teek.ScreenDistance(123) assert place_info['rely'] == 0.5 assert isinstance(place_info['relx'], float) assert isinstance(place_info['rely'], float) assert isinstance(place_info['x'], teek.ScreenDistance) assert isinstance(place_info['y'], teek.ScreenDistance) assert place_info['width'] is None assert place_info['height'] is None assert place_info['relwidth'] is None assert place_info['relheight'] is None button.place_forget() assert button.place_info() == {} button.place(**place_info) assert button.place_info() == place_info button.place_forget() assert window.place_slaves() == [] label1 = teek.Label(window, 'label one') label1.place(x=1) label2 = teek.Label(window, 'label two') label2.place(x=2) assert set(window.place_slaves()) == {label1, label2} # allow any order frame = teek.Frame(window) label2.place(in_=frame) assert window.place_slaves() == [label1] assert frame.place_slaves() == [label2]
def test_pack(): window = teek.Window() button = teek.Button(window) button.pack(fill='both', expand=True) pack_info = button.pack_info() assert pack_info['in'] is window assert pack_info['side'] == 'top' assert pack_info['fill'] == 'both' assert pack_info['expand'] is True assert pack_info['anchor'] == 'center' for option in ['padx', 'pady']: assert isinstance(pack_info[option], list) assert len(pack_info[option]) in {1, 2} for item in pack_info[option]: assert isinstance(item, teek.ScreenDistance) for option in ['ipadx', 'ipady']: assert isinstance(pack_info[option], teek.ScreenDistance) button.pack_forget() with pytest.raises(teek.TclError): button.pack_info() button.pack(**pack_info) assert button.pack_info() == pack_info button.pack_forget() assert window.pack_slaves() == [] label1 = teek.Label(window, 'label one') label1.pack() label2 = teek.Label(window, 'label two') label2.pack() assert window.pack_slaves() == [label1, label2] frame = teek.Frame(window) label2.pack(in_=frame) assert window.pack_slaves() == [label1] assert frame.pack_slaves() == [label2]
def __init__(self, window, bus, queue, *args, **kwargs): super().__init__(window, *args, **kwargs) self._bus = bus self._queue = queue def say_hello(): print("Hello.") def toggle_listener(): self._bus.emit("toggle_listener") frame = teek.Frame(window) frame.grid(column=0, row=0) """LABELS""" label_font_setting = ('Helvetica', 16) target1 = teek.Label(frame, text="Target 1 coordinates: ") target1.config['font'] = label_font_setting target1.grid(column=1, row=2, sticky="W", padx=20, pady=5) target2 = teek.Label(frame, text="Target 2 coordinates: ") target2.config['font'] = label_font_setting target2.grid(column=1, row=3, sticky="W", padx=20, pady=5) item_target = teek.Label(frame, text="Target Item coordinates: ") item_target.config['font'] = label_font_setting item_target.grid(column=1, row=4, sticky="W", padx=20, pady=5) stat_tier = teek.Label(frame, text="Minimum Stat Tier: ") stat_tier.config['font'] = label_font_setting stat_tier.grid(column=1, row=5, sticky="W", padx=20, pady=5) max_iterations = teek.Label(frame, text="Max # of iterations: ") max_iterations.config['font'] = label_font_setting max_iterations.grid(column=1, row=6, sticky="W", padx=20, pady=5) target_1_limit = teek.Label(frame, "Target 1 currency limit: ") target_1_limit.config['font'] = label_font_setting target_1_limit.grid(column=5, row=2, sticky="W", padx=20, pady=5) target_2_limit = teek.Label(frame, "Target 2 currency limit: ") target_2_limit.config['font'] = label_font_setting target_2_limit.grid(column=5, row=3, sticky="W", padx=20, pady=5) status_label = teek.Label(frame, text="Program Status Updates: ") status_label.config['font'] = label_font_setting status_label.grid(column=8, row=1, columnspan=2, sticky="WS", pady=5) # Cycles current_cycle_num = teek.IntVar() current_cycle_num.set(0) cycle_number_label = teek.Label(frame, "Current Cycle: ") cycle_number_label.config['font'] = label_font_setting cycle_number_label.grid( column=8, row=7, sticky="WS") cycle_number_count = teek.Label(frame, text=current_cycle_num.get()) cycle_number_count.grid( column=9, row=7, sticky="WS") """VARIABLES""" """ To use variables, you can't just try to manually assign them like you would normally in Python. a = 10 won't work. In the case of a, you'd need to write a.set(new_value) because we're technically using a subclass of TclVariable. We need to use the getter/setter methods to access and modify data stored in each object instance. """ # Do I even need these? If I'm already storing these as a tuple in the preset, I might not need this. t1_x_var = teek.FloatVar() t1_y_var = teek.FloatVar() t1_var_tuple = (t1_x_var, t1_y_var) t2_x_var = teek.FloatVar() t2_y_var = teek.FloatVar() t2_var_tuple = (t2_x_var, t2_y_var) target_item_x = teek.FloatVar() target_item_y = teek.FloatVar() target_item_tuple = (target_item_x, target_item_y) # I may want to define the defaults inside the Preset class. # These presets are more of a data attribute that should be handled elsewhere. t1_limit_var = teek.IntVar() t1_limit_var.set(5000) t2_limit_var = teek.IntVar() t2_limit_var.set(5000) item_stat_tier = teek.IntVar() item_stat_tier.set(1) stat_tier_entry = teek.Entry(frame, text=item_stat_tier.get()) stat_tier_entry.grid(column=2, row=5, sticky="W") max_iterations = teek.IntVar() max_iterations.set(5000) set_preset_name_label = teek.Label(frame, text="Set Preset Name: ") set_preset_name_label.grid(column=5, row=6, sticky="W") set_preset_name = teek.StringVar() """BUTTONS""" target_1_set = teek.Button( frame, text="Set target 1 (x,y)", width=15, command=toggle_listener) target_1_set.grid(column=3, row=2, sticky="W", padx=3) target_2_set = teek.Button( frame, text="Set target 2 (x,y)", width=15, command=say_hello) target_2_set.grid(column=3, row=3, sticky="W", padx=3) item_target_set = teek.Button( frame, text="Set item target (x,y)", width=15, command=say_hello) item_target_set.grid(column=3, row=4, sticky="W", padx=3) """INPUT FIELDS""" # Will need to BIND these. max_iteration_input = teek.Entry(frame, text=max_iterations.get()) max_iteration_input.grid( column=2, row=6, columnspan=2, sticky="W", padx=3) t1_limit_input = teek.Entry(frame, text=t1_limit_var.get()) t1_limit_input.grid( column=6, row=2, sticky="W", padx=3) t2_limit_input = teek.Entry(frame, text=t2_limit_var.get()) t2_limit_input.grid( column=6, row=3, sticky="W", padx=3)
import teek def on_click(): print("You clicked me!") window = teek.Window() button = teek.Button(window, "Click me", command=on_click) button.pack() window.on_delete_window.connect(teek.quit) teek.run()