How to react on actions (events) in real time in Tkinter? - python

I´d like to create a program which will react on actions by user in real time. For example there will be three Labels. And when user clicks on one, I want to recolor the border to a different color and the user should be able to "type" a (single) number in this Label. I know about the Entry widget, but Labels are suitable for the whole application.
Thank you for any answers

Your question is too vague to answer precisely, but to specifically address each individual point:
Yes, it's possible to "react .. in real time" -- whenever an event is detected it will be acted upon as soon as possible.
Yes, it's possible to color the border of a widget when an event is detected
Yes, it's possible to type into a label. Though, obviously, the behavior is unusual and may not be what you expect.
I suspect none of those help you solve your real problem, but I have no idea what you're actually trying to accomplish.

Related

What is the difference between a Primitive, Control and Complex Control widget?

Qt supports custom paint events for drawing of widgets through QStyle.
However when using the QStyle you need to specify what type of element you're trying to draw,
i.e, if you want a control element you need to paint it by using QStyle.drawControl(CE_Example, style).
My question is, how is someone who is relatively new meant to understand which method to correctly call, or find which element to paint when I want to perform the actions myself, say for example I want to draw my SpinButton with purple up and down arrows. I tried to google and see if I could find an explanation but could not, so I was wondering if this is common terminology or if it was some jargon used by the Qt community.
Any advice for correctly traversing documentation or anything like that appreciated, maybe I have an incorrect approach.
I eventually found my answer traversing https://doc.qt.io/qt-5/qstyle.html#details
Primitive Element: A primitive element is a common GUI element, such as a checkbox indicator or button bevel.
Control Element: A control element is a part of a widget that performs some action or displays information to the user.
Complex Control: Complex controls have different behavior depending upon where the user clicks on them or which keys are pressed.

In PyQt5, if you have multiple checkboxes how to direct to function if not a specific one but any is checked?

I have a program I'm developing using PyQt5 where I have 6 QComboBoxes to make selections from, and then based on these selections you can narrow down the data further. For clarity, it looks like this:
Image of Program
If something is in the "weakness" category I want the user to have the option to remove it from the final selection process in case the initial results are too narrow.
Here's where the problem is:
The final calculation is based on what checkboxes are checked. To make sure this is as reflected in the GUI I do the following things whenever a combobox is changed:
Changed the QStackedWidgets to the "deactivated" label
Determine strengths and weaknesses based on type data from comboboxes
Unchecked all the checkboxes and mark the appropriate ones as checked.
Code for this is below:
#deactivate all stacks
for t in range(0,18):
str_type0 = self.value[t].lower()[0:3]
str_stack0 = 'self.str_'+str(str_type0)
eval(str_stack0).setCurrentIndex(0)
weak_type0 = self.value[t].lower()[0:3]
weak_stack0 = 'self.weak_'+str(weak_type0)
eval(weak_stack0).setCurrentIndex(0)
#strong loop
for t in range(0,len(self.r)):
str_type = self.value[self.r[t]].lower()[0:3]
str_stack = 'self.str_'+str(str_type)
eval(str_stack).setCurrentIndex(1)
#weak loop
for t in range(0,len(self.q)):
weak_type = self.value[self.q[t]].lower()[0:3]
weak_stack = 'self.weak_'+str(weak_type)
eval(weak_stack).setCurrentIndex(1)
#set all checkboxes as checked if currently shown in stack
for t in range(0,18):
checkstr0= self.value[t].lower()[0:3]
checkstr1='self.weak_'+str(checkstr0)+'_act'
eval(checkstr1).setChecked(False)
weak_stack1 = 'self.weak_'+str(checkstr0)
weak_stack1 = eval(weak_stack1)
if weak_stack1.currentIndex() == 1:
eval(checkstr1).setChecked(True)
else: continue
This is fine and works even if it's a little clunky (goal is tomake it work and then make it work efficiently later). The issue is that changing a checkbox is what triggers the function that does all the calculating for the results, but since multiple checkboxes change at the same time, or even just changing one, triggers this function a multiplicity of times. It's a huge waste of computation.
I've thought of some solutions. I think perhaps the best way to solve this problem is to run the function not when any particular checkbox changes but there is a change. Something like:
if any (checkbox.checkState()==changed): do something.
I'm not sure if that would be a good solution, or how to even do that.
Any ideas are appreciated. Thanks in advance!
Figured out the answer while I continued to think about the problem. The problem was that it signaled every time it changed, which is a horrible amount while the program configured itself.
The obvious yet simple solution was to change the checkboxes from:
checkbox.stateChanged.connect(function)
to
checkbox.pressed.connect(function)
This way the checkbox signal will only go forth when I physically press on it in the program. Hopefully this will be able to help anyone else out there who runs into the same issue in the future.

Is there a way for a multiple line (with multiple entry field in each) screen design in Tkinter (or another module) in Python?

If I want to have a multiple-line screen design (with multiple fields in each), is there a widget or something to achive this in Python?
Say for instance, I will make an inventory item entry screen with 20 lines(or more), in each there will be these fields:
Item no (char&input capable)
item name (output only and depending on my input for item no it will be displayed promptly)
amount (integer&input capable)
unit(char&input capable)..
I must be able to make data entry or update freely in whichever line I want and when I am done, with a push-button I must be able to save them all..
For such a screen design, is there a standardized way of having a multiple line with multiple entry field facility in Tkinter or another module in Python?
If there is not, how do you design such data entry screens in Python? I still couldn't find it anywhere, so I wanted to open this question here for discussion.. Thank you all..
Yes, you can have a "multiple-line screen design" in tkinter. tkinter can handle almost any type of layout you can imagine. There is no standardized way to do that because no two GUIs are the same.
How do you go about designing such a screen? First, with pencil and paper. The way to implement it would probably be easiest using the grid geometry manager, though the actual implementation depends on a lot of factors related to exactly what you want to do.
Thank you very much for your replies guys, at the beginning I thought I would need to define 80 entry fields as variables for 20lines&4 fields in each, and said noway! But gridding and the code snippet below which I encountered somewhere put how in a single for loop we can create the whole screen all at once.. and by event handling and getting the row variable where cursor is on we can manage the whole screen and fields, yes its very practical:)
Thanks again for sparing your valuble time:)
from Tkinter import *
colours = ['red','green','orange','white','yellow','blue']
r = 0
for c in colours:
Label(text=c, relief=RIDGE,width=15).grid(row=r,column=0)
Entry(bg=c, relief=SUNKEN,width=10).grid(row=r,column=1)
r = r + 1
mainloop()

Best practice for TextInput validation in kivy/kv

I'm designing a GUI for android with kivy. There are many TextInput-fields, most of them need some kind of validation. What I've found so far is, that on_text_validate would allow for plausibility checks, but only if the user leaves that field with ENTER, which is rarely the case in an android-environment. How can I achieve checks if the user sets the focus to another widget by tapping?
Doing this (allways) with on_text seems a bit weird to me, but maybe it's possible. A simple example: how would you make sure that the user is only able to insert integers and that the value is in a definite range?
The other question I would like to ask: how is it possible to deactivate a TextInput depending on the value of previous inputs or to set the focus appropriately?
I think these are standard tasks in GUI-programming and I'm a bit confused on how to manage these in kivy - help would be very appreciated!

Dynamically indenting and highlighting words in tkinter textbox

I recently made a simple notepad-like text editor but now I want to implement things like syntax highlighting certain words and automatic indentation as you type. How could I do this dynamically as the user types. So far everything I've done is event-based so I'm guessing I need to have some sort of loop that constantly checks the contents of the textbox as the user is typing? Is tkinter not suited for this? Appreciate it if you steer me in the right direction as to how I can implement this.
Tkinter is quite well suited to this sort of thing. It's possible to make a very smart text editor if you're willing to put in some effort.
This answer shows how to get the text widget to fire an event whenever something in the text widget changes. It's a little complicated, but fairly foolproof.
If you want something simpler, you can simply bind on <Any-KeyRelease> which will fire an event whenever the user releases a key. You can then use the information in the event object to decide what to do. It won't handle the case where you cut and paste with the mouse, for example, and your binding will fire for arrow keys and other non-inserting keys, which is why I recommend the more complicated solution.
This answer shows an example of using a binding on <space> to do do a simple spellcheck, and also shows a fairly simplistic implementation of a toolbar with a "bold" button.

Categories

Resources