Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Is it possible to Limit the decimals of a float?
-
@RocketBlaster05, look at
decimal.Decimal
, it handles decimal (duh) numbers sanely. -
@cvp I have it applied to a text field in a presented ui. The sample you showed works but not when I implement it as such:
class MyTextFieldDelegate (object): def textfield_should_change(self, textfield, range_c, replacement): # Build field value if replacement would be accepted fld = textfield.text #print(fld, range_c, replacement) if replacement == '': # Backspace or cut to remove textfield[range[0]to[range[1]-1] new = fld[:range_c[0]]+fld[range_c[1]:] else: # replacement could even be more than 1 character if paste new = fld[:range_c[0]]+replacement+fld[range_c[0]:] i = new.find('.') l = len(new.rstrip()) if i < (l-3): return False return True tf = ui.load_view('GlassInput')['textview1'] tf.delegate = MyTextFieldDelegate() #No errors pop up but delegate doesn’t work when view is presented elsewhere
-
@RocketBlaster05 said: incorrect
tf = ui.load_view('GlassInput')['textview1']
try
v = ui.load_view('GlassInput') tf = v['textview1']
-
@RocketBlaster05 use à TextField instead of a TextView
-
@cvp this is all my code for the process I’m trying to complete. I’ve done all you have said yet it doesn’t work. Everything gets properly presented but the delegate just isn’t applied:
def text_entered_glass(sender): global userinput userinput = sender.text try: input = float(userinput) roundedinput = round(input, 2) if roundedinput <= 10 and roundedinput >= 0: global gltot gltot += roundedinput v.name = str(gltot) with open(fil3,mode='wt') as f: f.write(str(gltot)) m.changetotals() print (gltot) nav.close() else: ui.load_view('GlassError').present('sheet') except ValueError: ui.load_view('GlassError').present('sheet') class MyTextFieldDelegate (object): def textfield_should_change(self, textfield, range_c, replacement): # Build field value if replacement would be accepted fld = textfield.text #print(fld, range_c, replacement) if replacement == '': # Backspace or cut to remove textfield[range[0]to[range[1]-1] new = fld[:range_c[0]]+fld[range_c[1]:] else: # replacement could even be more than 1 character if paste new = fld[:range_c[0]]+replacement+fld[range_c[0]:] i = new.find('.') l = len(new.rstrip()) if i < (l-3): return False return True gi = ui.load_view('GlassInput') tf = gi['textfield1'] tf.delegate = MyTextFieldDelegate() ```
-
@RocketBlaster05 I see that the input field is named TextField1 but is it a TextField or a TextView?
And where do you present the view named gi ?
Do you use twice ui.load_view('GlassInput')?
Perhaps, could it be better if you post your entire code...
-
@cvp alright but this is might be a wild ride:
class Menu(ui.View): # Main Menu setup def __init__(self): ui.View.__init__(self) self.scene_view = scene.SceneView() self.present(hide_title_bar=True) self.scene_view.frame = self.bounds self.scene_view.bg_color = '#4fb357' self.add_subview(self.scene_view) self.mm = ui.load_view('MainMenu') self.mm['imageview1'].image = ui.Image('companylogo.PNG') self.changetotals() self.mm.present('fullscreen', hide_title_bar=True) def changetotals(self): #just updates stats below if os.path.exists(fil): with open(fil,mode='rt') as f: global wbtot wbtot = int(f.read()) else: wbtot = 0 if os.path.exists(fil2): with open(fil2,mode='rt') as f: global cbbtot cbbtot = int(f.read()) else: cbbtot = 0 if os.path.exists(fil3): with open(fil3,mode='rt') as f: global gltot gltot = float(f.read()) else: gltot = 0 if os.path.exists(fil4): with open(fil4,mode='rt') as f: global paptot paptot = float(f.read()) else: paptot = 0 self.mm['textview1'].text = 'Water Bottles Recyled: ' + str(wbtot) self.mm['textview2'].text = 'Cardboard Boxes Recycled: ' + str(cbbtot) self.mm['textview3'].text = 'Glass Recycled: ' + str(gltot) + ' lbs' self.mm['textview4'].text = 'Paper Recycled: ' + str(paptot) + ' lbs' def glass_pressed(Glass): # ui button on main menu global v v = ui.load_view('GlassInput') rm.update_menus(nam='View4', col='#4fb357') # changes a navigation view tab to open glass input page; possible source of error class MyTextFieldDelegate (object): # The delegate script def textfield_should_change(self, textfield, range_c, replacement): # Build field value if replacement would be accepted fld = textfield.text #print(fld, range_c, replacement) if replacement == '': # Backspace or cut to remove textfield[range[0]to[range[1]-1] new = fld[:range_c[0]]+fld[range_c[1]:] else: # replacement could even be more than 1 character if paste new = fld[:range_c[0]]+replacement+fld[range_c[0]:] i = new.find('.') l = len(new.rstrip()) if i < (l-3): return False return True def text_entered_glass(sender): # Textfield input process global userinput userinput = sender.text try: input = float(userinput) roundedinput = round(input, 2) if roundedinput <= 10 and roundedinput >= 0: global gltot gltot += roundedinput v.name = str(gltot) with open(fil3,mode='wt') as f: f.write(str(gltot)) m.changetotals() print (gltot) nav.close() else: ui.load_view('GlassError').present('sheet') except ValueError: ui.load_view('GlassError').present('sheet') v = ui.load_view('GlassInput') #attempt at setting delegate tf = v['textfield1'] tf.delegate = MyTextFieldDelegate() class RecycleMenu(): # Navigation menu setup mentioned earlier def __init__(self): self.background_color = '#4fb357' self.start_NavView() def start_NavView(self): self.view = ui.load_view('RecycleMenuOptions') self.view.name='Home' global nav nav = ui.NavigationView(self.view) nav.present(hide_title_bar=True) def update_menus(self, nam=None, col=None): v.name = nam v.background_color = col nav.push_view(v)
-
@RocketBlaster05 it is what I thought, you have twice your view...
Move the tf = after the first onedef glass_pressed(Glass): # ui button on main menu global v v = ui.load_view('GlassInput') tf = v['textfield1'] tf.delegate = MyTextFieldDelegate() rm.update_menus(nam='View4', col='#4fb357') # changes a navigation view tab to open glass input page; possible source of error
Then remove the second one
#v = ui.load_view('GlassInput') #attempt at setting delegate #tf = v['textfield1'] #tf.delegate = MyTextFieldDelegate()
You also would need to move the class MyTextFieldDelegate before the def glass_pressed.
Please, try these modifications and tell me....
-
@cvp YES YES YES YES YES!!!!!!! Thank you so much it is finally working as planned!
-
-
@cvp you are the man don't let anybody tell you otherwise!
-
@RocketBlaster05 you are too kind. Do you agree that I forward your sentence to my wife? 😂
-
@cvp without a doubt my man
-
@cvp I've been messing around testing all the functions of the app but occasionally when I rerun the program the textview under the changetotals() function adds an extra .0000000000001 to the end of the number and I don't know why. Any Ideas?
-
I assume it is related to the delegate... If you press more than the delegate allows it bugs out the number every now and then for some reason.
-
@RocketBlaster05 Are should sure that textfield1 is a TextField not a TextView in your pyui?
-
@cvp yes
-
@RocketBlaster05
text_entered_glass is called after the delegate. Is your round still needed? -
@cvp Here is what I have it set to now:
def text_entered_paper(sender): global userinput userinput = sender.text try: input = float(userinput) if input <= 5 and input >= 0: global paptot paptot += input v.name = str(paptot) with open(fil4,mode='wt') as f: f.write(str(paptot)) m.changetotals() print (paptot) nav.close() else: ui.load_view('PaperError').present('sheet') except ValueError: ui.load_view('PaperError').present('sheet') ```
-
@RocketBlaster05 and is your userinput erroneous ?