Kivy: Reset/Default values to all widgets on a screen? - python

Is there a way to return all values of all widgets on a screen to their default values (ex. TextInputs text: '') or do I have to write a function to go through each one, one by one, to clear them?

I don't think Kivy properties retain any concept of a default value, so you'll have to handle this yourself.

What you can do is clear all widgets on a screen using .clear_widgets() function. I don't think there's any way to reset all values. Another way to change the values is like if you have a textfield then you can do textfield.text = '' but you have to go through each widget to reset it

Related

Make a number restricted QLineEdit box amend to two decimal places when focus is lost? [duplicate]

I have a QLineEdit in my project.
I want to use the QValidation on lineEdit.
#Create lineEdit
itemValue = QtWidgets.QLineEdit()
#Create валидатор
objValidator = QtGui.QDoubleValidator(self)
#setup range
objValidator.setRange(-10.0, 100.0, 5)
#lineEdit with validation
itemValue.setValidator(objValidator)
But it doesn't work well.I can type what i want, except symbols.
And range doesn't work!I can type 100500 or -100500, but i want, that user can enter numbers only in range.
How i should use range?
I need help:)
Thanks for your help, guys!
By default, a validator will not prevent values outside the range from being entered, and it won't prevent the user leaving the line-edit if the entered value is Invalid or Intermediate.
However, it does give you an opportunity to reject the input programmatically, because whenever the current value is unacceptable, the line-edit won't emit its editingFinished or returnPressed signals, and its hasAcceptableInput method will return False. In addition, if you subclass the validator, you can reimplement its fixup method to control the values that are entered.
However, as has been suggested already, a far better/simpler solution is to use a QDoubleSpinBox, since it cleans up the input automatically and provides a more user-friendly interface.
As an alternative you could use a QDoubleSpinBox.
has validator build in
prevents invalid input while typing
has build-in setRange()
and adds a little handle to change the value for more mouse oriented users.
Probably you are expecting something what should not happen.
In general when you have validator you should be able to type something in intermediate state what doesn't exactly meet limitation. But this should be fixed, when editor looses focus.
Why? Imagine you have 84 an you want correct this to -8.4. Many people will do this like that: add minus so now you have -84 which is not acceptable then add dot. If validator fixes this immediately it would be annoying for user.
So bottom line does this "problem" happen when editor looses focus?

Refer to tkinter widget by its instance

I am learning Python w/ Tkinter and I recently learned the difference between the reference and the name/instance of a widget. The reference is the string you assign to a widget (which can be changed later on), but the name seems to be the actual identity of the widget (which is immutable). Essentially it seems as though the reference is a nickname of a widget because it can change overtime and be different depending on who you are talking to, while the actual name of the widget on the widget's drivers license is always the same. Specifically, in this line of code...
sample_frame = Frame(root, name = 'frame1', bg = 'blue', height = 50, width = '50')
"sample frame" is the reference, while 'frame1' is the name.
Unless I specifically assign the string 'frame1' as the name of this frame, python automatically generates a number sequence as its name. In order to view the name of any widget you just have to add...
print(str(sample_frame))
(the output in this example is .frame1)
So in Tkinter if I wanted to place this frame in my GUI i would have to pack/grid/place it in the following line like so...
sample_frame.pack()
But what I would like to do is call the pack method on this frame widget by its name rather than its reference. Something like this...
frame1.pack() #or
.frame1.pack() #because of that period
The problem is that Python claims frame1 was never defined, and .frame1 is invalid syntax. Does anybody know how to do something like this? Thanks.
For broader context I am doing this because I iterated the creation of 21 different frames and placed them in a 3x7 grid. Because of this all 21 frames have an identical reference. BUT, I made sure to make the name of each frame corresponds with its position.
The name= option sets the name of the widget within the Tcl environment that actually implements the GUI - it has no effect on the Python side. The only reason I can think of for doing this is that it might make Tcl error messages somewhat easier to read (the auto-generated widget name that you'd otherwise get is not particularly meaningful).
As always, the proper way to deal with multiple objects created in a loop is to store them in a container of some sort. In your case, it could be a 21 element list, a nested list (widget[row][column]), or perhaps a dict indexed by tuples (widget[row, column]).
While I fully agree with jasonharper's answer that you should keep a proper reference to the widgets and I do not recommend using what I'm about to explain, there actually is a way to achieve what you're asking. There's a widget method called nametowidget(), which returns the widget object when you give it a name. Note that you should call the method on the object (Tk, Toplevel, Frame) that contains the widget you're looking for.
So following your example, this works:
from tkinter import *
root = Tk()
sample_frame = Frame(root, name = 'frame1', bg = 'blue', height = 50, width = '50')
root.nametowidget('frame1').pack()
root.mainloop()
And if you would do the same with a button inside the frame you should do:
sample_button = Button(sample_frame, text='Button', name='button1')
sample_frame.nametowidget('button1').pack()

PyQt: is there an better way to set objectName in code?

When you use Qt_Designer or Qt_Creator to design a form, objectName for any given widget is always set to something. But if you create a widget in code AND you need the objectName later, you have to assign it explicitly. So then the widget assignment takes at least two lines of code. This seems very inelegant.
Example:
button1 = QPushButton('button caption') # at this point objectName is some kind of empty string
button1.setObjectName('button1')
If you need to find the widget later (i.e. with findChild), you must have objectName set, otherwise you're out of luck.
Is there some way to automatically set objectName without extra lines of code? I looked at the PyQt5 Reference Guide and could not find such a feature. A similar question was asked on Code Review, but got no answers. Two lines of code isn't the end of the world, but it seems redundant. Somehow I'm required to assign this name twice once for Python (first line) and again for Qt.
You can pass objectName as a keyword argument when creating the button.
button1 = QPushButton('button caption', objectName='button1')
This can extend this to any Qt property during initialization:
button1 = QPushButton(text='button caption', objectName='button1', icon=icon1)
Moreover, signals can be connected when constructing an object, too:
button1 = QPushButton(text='button caption', objectName='button1', clicked=someMethod)
The added named argument is equivalent to button1.clicked.connect(someMethod)

PyQt QLineEdit with QValidator

I have a QLineEdit in my project.
I want to use the QValidation on lineEdit.
#Create lineEdit
itemValue = QtWidgets.QLineEdit()
#Create валидатор
objValidator = QtGui.QDoubleValidator(self)
#setup range
objValidator.setRange(-10.0, 100.0, 5)
#lineEdit with validation
itemValue.setValidator(objValidator)
But it doesn't work well.I can type what i want, except symbols.
And range doesn't work!I can type 100500 or -100500, but i want, that user can enter numbers only in range.
How i should use range?
I need help:)
Thanks for your help, guys!
By default, a validator will not prevent values outside the range from being entered, and it won't prevent the user leaving the line-edit if the entered value is Invalid or Intermediate.
However, it does give you an opportunity to reject the input programmatically, because whenever the current value is unacceptable, the line-edit won't emit its editingFinished or returnPressed signals, and its hasAcceptableInput method will return False. In addition, if you subclass the validator, you can reimplement its fixup method to control the values that are entered.
However, as has been suggested already, a far better/simpler solution is to use a QDoubleSpinBox, since it cleans up the input automatically and provides a more user-friendly interface.
As an alternative you could use a QDoubleSpinBox.
has validator build in
prevents invalid input while typing
has build-in setRange()
and adds a little handle to change the value for more mouse oriented users.
Probably you are expecting something what should not happen.
In general when you have validator you should be able to type something in intermediate state what doesn't exactly meet limitation. But this should be fixed, when editor looses focus.
Why? Imagine you have 84 an you want correct this to -8.4. Many people will do this like that: add minus so now you have -84 which is not acceptable then add dot. If validator fixes this immediately it would be annoying for user.
So bottom line does this "problem" happen when editor looses focus?

How do I iterate through all wx.CheckBox instances?

I have a wx frame where I have a quite a few checkboxes. Ever so often when the user changes the settings in a drop down menu (wx.ComboBox) I'd like to clear all the checkboxes. Currently, I've implemented a method that gets called when a change in the ComboBox happens and it clears each check box manually, i.e.:
def ClearCheckBoxes(self):
self.cb_EnableControl.SetValue(0)
self.cb_EnableRun.SetValue(0)
self.cb_EnablePower.SetValue(0)
...
...
Although I only have about 10 of these, my ClearCheckBoxes method would be much cleaner if it were something like this:
def ClearCheckBoxes(self):
for CheckBox in self.AllCheckBoxes:
CheckBox.SetValue(0)
Also, I suppose I could create a list (i.e. AllCheckBoxes) and add all the checkboxes to the list as I create them, and then it would only be a matter of iterating through the list. But the point here is that I'd like to know if there was an pre-defined way of doing this.
Thanks
for control in self.GetChildren():
if isinstance(control, wx.CheckBox):
control.SetValue(False)
Have you tried something super ugly like:
[checkbox.SetValue(0) for checkbox in dir(self) where type(checkbox) == type(wx.Checkbox)]

Categories

Resources