I am able to use activeforeground and activebackground to change color in background/text when button is clicked in tkinter.
Is it possible to do the same thing in customtkinter as well? I have checked the website if similar context is available, however, could not see any.
Thanks in advance.
From both the documentation and the GitHub webpage, I could not see any changes that would suggest this is possible.
You cannot have it on the button event function, so that the moment the button is clicked, the background and foreground is changed and then it is changed back to the normal. This is beacuse the the switch will be too fast and it does not work if you add sleep().
The closest work around that you can have is probably just to have it on the hover event as I belive the Hover event may be interfering with the changing of the colour in runtime straight away. If this is a deal breaker you may want to use PySide2/6 instead as they do have this exact custimastion readily availabe.
Also for anyone else interested in Custom Tkinter, make sure to use the GitHub page to see any progress or fucntions as it is mantained, the best documentation is from the Wiki found at:
https://github.com/TomSchimansky/CustomTkinter/wiki
I'm learning how to program in Python and use the PIL (Pillow) in order to create small bots which can recognize changes in the screen in order to execute repetitive commands (keyboard presses with pynput module).
I did a small GUI with Tkinter in order to get user information regarding the parameters which the user is going to use (Entry widgets) at their use of the bot and I also need a few buttons for enabling/disabling certain parts of the code (i'm using check buttons and using boolean logic in order to enable/disable) and also for enabling the main function of the bot (which is to press a button once it recognizes a certain change at the screen).
What I am currently experiencing is that the once I run my program, it opens up my GUI and all that a user would see but it doesn't execute my main function, it only executes the main function AFTER I close the GUI.
I'd love to post my code but it exceeds 220 lines and it would probably become even more confusing.
So, long story short, is it a kind of error which happens a lot when inexperienced programmers try to create softwares with tkinter? If yes, what causes it and how can it be fixed?
I appreciate any help you guys can get me. :]
...creates frames, widgets, entries...
mainHealerVar = IntVar()
main_healer_check = Checkbutton(root, text="Enable the bot", variable=mainHealerVar) #this should mean that when i press this checkbutton it'll enable the bot and perform the repetitive commands for as long as it stays checked
... some more buttons/code...
root.mainloop() #right after I stop setting up the GUI, I place this function
... make logic in order to know which part of the repetitive functions to execute...
if mainHealerVar.get() == 1:
mainHealFunction() #function to check if the checkbutton is still pressed (if it is, it should execute mainHealFunction()
It was supposed to execute the repetitive commands by the pynput module as soon as i clicked on the enabling Check-button, but it doesn't execute anything until I close the GUI, then it starts to execute the repetitive commands. I have also tried using a while loop instead of an "if" at the end, but ended up with the same result.
I designed a character creation page, and included a bit where a person can input their name with ui.input() but the problem is, they can't push any buttons or do anything at all without submitting the text first and I am trying to figure out how to turn this ui.input into a clickable so it is only active when its selected.
Then engine has a page on the ui.input (and includes explaining that the button arg is possible) but it doesn't really give me any other example other than button=None. and anything else I try, the game won't even load.
Sorry if this is a really noob question. Seems like the most simple thing.
This is what I have for that part if it helps..
ui.input('', xalign=0.5, yalign=0.5)
first_name = ui.interact()
How about creating a character creation screen and using a graphic button?
In a custom screen, you can control everything using buttons and code, which is, in some senses, outside of your story.
If there are lets say 4 buttons, all with the same Click event, how can I find out which button was pressed?
if the event looks like this def Button_Click(self, sender, e): I'm sure I can compare sender to my buttons somehow. But how?
Well, I've never used IronPython so I don't know how much help this will be, but what I usually do when trying to figure out these things in regular python is to print type(sender) , print sender and print dir(sender) to console(or output to a file if you don't have a console available).
This should help you figure out what exactly is the "sender" parameter. In the simplest case it could be the button itself so a simple == will work to know which button it was. Or it could have a method/property that gets you the button object. In which case, dir(sender) might contain an obvious one, or if not, google the class name gotten from type(sender) and see if you can find any docs.
How to suppress end user ability to edit/add/delete text in a Text widget? (Python v3.2.. and tkinter)
The point is to suppress only the ability to change/add/delete text but not to castrate other features. Perhaps a NoEdit Text widged would be a better name.
I've tried .text['state'] = 'disabled' and it works almost OK in Windows (it still allows user to select/copy text highlights the selection, page up/down and up/down buttons work. The only thing broken seems to be the cursor made invisible.)
But on MacIntosh everything is broken. No highlights, no select/copy,... UGH
Since Tkinter has practically no documentation in Python, I've searched and found some TCL advise, to derive a new class and suppress the insert and delete functions.
So, I've tried as so:
class roText(tk.Text):
def insert(self,*args,**kwargs):
print(" Hey - Im inside roText.insert")
pass
def delete(self,*args,**twargs):
pass
def pInsert(self,*args,**twargs):
super().insert(*args,**twargs)
Unfortunately it didn't work right. Apparently tkinter does not use those insert and delete functions when end user enters/deletes code. Perhaps those TCL insert/delete are something else, and I lost something in translation from TCL and Swahili. What functions does tkinter.Text use for end user editing text? Hopefully they are not internal...
So, is there a way to modify the Text widget to suppress only end user editing?
Is there a way to do it without diving inside and overriding internal Tkinter code, so the stuff doesn't get broken by next releases of Tkinter?
Looking at the Idle shell window, I see that they've managed to suppress edits (except for the last line). So there is a way. But what is it and how costly?
Sorry for bumping an old question, but I was searching for an answer to this question also and finally found a solution. The solution I found involves overriding the key bindings when the text widget has focus and is pretty simple. Found here.
To override the bindings of a widget there is a bind function where you pass a string of what is to be overridden and the new function you want it to call.
self.txtBox.bind("<Key>", self.empty)
Somewhere else in the class you'll need to define the function to handle the event.
def empty(self, event):
return "break"
By returning the string "break" the event handler knows to stop after your function, instead of continuing with the default action.
I hope this answers your question. Cheers.
The reason the disabled state doesn't seem to work on the Mac is because it turns off the binding that gives focus to the widget. Without focus, the highlighting on a Mac doesn't show up. If you set the state to disabled but then assign a binding to <ButtonPress-1> to explicitly set focus to the disabled text widget, you can then select and copy text and the highlighting will show.
As for the cursor disappearing... arguably, that's what's supposed to happen. The cursor tells the user "this is where text will get inserted". Since no text will get inserted, having that visual clue would be confusing to the user. What you could do instead, if it was really important, is to insert a small image wherever they click to simulate the cursor.
To answer your question about whether the widget actually uses the insert and delete methods: the methods on the actual underlying widget are what the default bindings use, so overriding them in a subclass has no effect. You would need to redo all the default bindings for that to work. It's doable, but a lot of work.
Unfortunately, this is one area where programming in Tcl really shines, because you can simply disable the insert and delete commands of the widget. Of course, you can do that directly in Tkinter also since ultimately it runs tcl code to do everything, but that would involve writing some tcl code which is not a very good solution from the perspective of a Python coder.
I think the best solution is to use the disabled state, then add in just enough bindings to do what you want.
Here's a simple example that works by explicitly setting focus on a mouse button click. With this code I'm able to click and swipe to select a region, or double- or triple-click to select words and lines:
import Tkinter as tk
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.text = tk.Text(width=40, height=20)
self.text.bind("<1>", self.set_focus)
self.text.insert("end", "\n".join(dir(tk.Tk)))
self.text.configure(state="disabled")
self.text.pack(fill="both", expand=True)
def set_focus(self, event):
'''Explicitly set focus, so user can select and copy text'''
self.text.focus_set()
if __name__ == "__main__":
app = SampleApp()
app.mainloop()
#BryanOakley It took me a while to test your suggestion since I have no Mac.
Unfortunately Mac implementation of Python is buggy.
I've added focus, ie my disable function which I call after creating a window and inserting text, now calls first:
self.txt['state'] = 'disabled'
and then
self.txt.focus_set()
Which is what I think you've suggested.
It "kind of" worked. Ie: when selecting text (click and drag or double-click) highlighting works most of the time. Python must have some bad memory references or such bugs: Sometimes highlighting doesn't work at first, then it starts working (in the same window) after more clicking. Sometimes when program is invoked it works right of the bat. Sometimes selecting with Shift-rightArrow key will work but selecting with the mouse will not. Then starts working again. Or it will work fine in one window but not in another one (both of the same class), then starts working in all windows...etc...
The good thing is that adding focus did not affect badly Windows (ie all works fine as without focus.
I guess at this point I will just hope that future/next release of Python for Mac will fix those bugs..
BTW, it seems that Mac is a bit of an orphan for Python. Implementation is much uglier then for Windows. I mean the fonts look worse, the buttons, etc.. Or it could be due to different screen resolutions and Python ports that poorly account for those. Not sure
Anyway. Thank you for your help and suggestion to use focus for Mac.