Bir GUI geliştiriyorum ve bu gui de entry kullanıcam fakat entry sadece integer değerleri alması gerekiyor , herhangi sayı dışı bir şey giridliğinde kabul etmemesi ve entrye yazmaması gerekiyor .İnternette bakındım bir cevap bulamadım. Yardımlarınız için şimdiden teşekkürler…
Tkinterda kivy gibi int, string beya float gibi kullanıcı input kısıtlaması varmı tam olarak bilmiyorum. Ama kendiniz bi fonksiyon yazabilirsiniz bununla ilgili.
Örneğin
def ayikla(num) -> float:#sayı ayıkla
""" """
veri = str(num)
try:#eğer string cevrilebilicek ise
return round(float(num), 2)
except:
if not veri:#eğer boş string ise
return 0.0
elif veri.count(",") >= 2:#eğer birden cok virgül var ise sondakini noktaya dönüştür ve gerikalanını yok et
d = veri.rsplit(",", 1)
return round(float(d[0].replace(",", "") + "." + d[1]), 2)
elif veri.count(",") == 1:#virgülün bir adet olması durumunda
if len(veri) <= 4:# örn 1,22-12,1-1,2 vs
return round(float(veri.replace(",", ".")), 2)
elif len(veri) == 5:#1,236 farklı & 123,5-12,35 farklı
if veri.index(",") == 1:
return round(float(veri.replace(",", "")), 2) #1,236 durumu
elif veri.index(",") >= 2:#123,5-12,36 durumu
return round(float(veri.replace(",", ".")), 2)
elif len(veri) == 6:#1,2362-12,236-123,12-1236,5
if veri.index(",") <= 2:#1,2364-12,236 durumu
return round(float("".join(veri.replace(",", ""))), 2)
elif veri.index(",") >= 3:#123,56-1235,5 durumu
return round(float(veri.replace(",", ".")), 2)
elif len(veri) >= 7:#12345,6 - 1234,56
return round(float(veri.replace(",", ".")), 2)
for i in ["", 1, 1.4, "hebele"]:
print(ayikla(i))
Yukarıdaki fonksiyon gibi, tabi biraz daha geliştirilmesi gerekebilir.
Merhaba,
Entry
'i bir değişkene atayın daha sonra Entry
içine yazılmış olan veriyi .get()
ile alın.
Bu işlemden sonra şunu uygulayın
try:
#entry için atanmış değişken ismi userpass olsun
userpass.get() = int(userpass.get())
break
except:
#bu kısım eğer üstteki çalışmaz ise yapılacak işlemdir.
#if elif else gibi düşünün
etiket = Label(text="Lütfen sadece rakam giriniz")
etiket.pack()
Uygulamalı örnek göstereyim.
from tkinter import *
class Application(object):
def __init__():
self.main()
def main(self):
self.pencere = Tk()
self.pencere.geometry("250x250+100+100")
self.pencere.resizable(FALSE, FALSE)
self.userpass = Entry(self.pencere)
self.userpass.grid(row=0, column=1)
self.dugme = Button(self.pencere, text="Kaydet", command=self.kaydet)
self.dugme.grid(row=1, column=1)
def kaydet(self):
entry_degeri = self.userpass.get()
try:
entry_degeri = int(entry_degeri)
break
except:
self.uyari_etiket = Label(self.pencere, text="LÜTFEN SADECE SAYI GİRİNİZ")
self.uyari_etiket.grid(row=2, column=1)
app = Application()
mainloop()
inşallah bir yanlışlık olmaz kodları deneyecek platformum yok şuan hata alırsanız -ki inşallah almazsınız- burada iletişimde olalım
Şu işinizi görür sanırım:
import tkinter as tk
import string
root = tk.Tk()
def on_click(event):
if event.char == "": # sağ- sol ok tuşları ve belki bir kaç özel karakter daha
return True
if event.char.isalpha() or event.char.isspace() or event.char in string.punctuation:
return "break" # event tkinter tarafından işlenmiyor ve basılan tuş entry'e yazılmıyor
entry = tk.Entry()
entry.bind("<Key>", on_click)
entry.pack()
root.mainloop()
Bind’lenen event’lerin tkinter tarafından işlenmesini engellemeyi daha önce de araştırıp bulamamıştım, şimdi burada buldum.
Bir de bunu buldum:
import tkinter as tk
root = tk.Tk()
vcmd = root.register(str.isdigit)
entry = tk.Entry(root, validate = 'all', validatecommand = (vcmd, '%S'))
entry.pack()
root.mainloop()
@tevhidulvahset Kodunuzda birkaç hata var ve bu hali ile çalışmıyor. Ayrıca bu kod entry’e girilenleri en son kontrol eder, OP’nin istediği bu değil:
Kendimiz yazıyoruz, hazır hali yok diye biliyorum ben de.
Bu fonksiyon tam olarak ne işe yarıyor, biraz açabilir misiniz?
>>> ayikla("1,2324")
12324.0
>>> ayikla("12,1")
12.1
>>>
>>> ayikla("1,2,2")
12.2
>>> ayikla("1.2")
1.2
>>> ayikla("1..2")
>>> ayikla("1.2..")
>>> ayikla("1.2.3")
>>> ayikla("12.3")
12.3
>>> ayikla("1,2.3")
12.3
>>> ayikla("123.123,5")
Traceback (most recent call last):
File "C:\Users\user\Desktop\deneme.py", line 5, in ayikla
return round(float(num), 2)
ValueError: could not convert string to float: '123.123,5'
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "<pyshell#7>", line 1, in <module>
ayikla("123.123,5")
File "C:\Users\user\Desktop\deneme.py", line 26, in ayikla
return round(float(veri.replace(",", ".")), 2)
ValueError: could not convert string to float: '123.123.5'
>>>
Yapmak istediğiniz float gösteriminde .
yerine ,
kullanmak ise geçersiz girişlerde hata verilecek bir şekilde bu kolayca yapılabilir:
def ayikla(text: str) -> float:
return float(text.replace(",", "."))
for i in ("112", "0", "12,23", "213,89000"):
print(ayikla(i))
Ve bu kodun da OP ile alakası olduğunu sanmıyorum, soruda istenilen entry’nin sadece integer alması, float değil.
aslında bu fonksiyonu kendi kodlarına entegre etmesi için örnek olarak verdim. O nokta olayı ise genelde klavyenin sayı bölümündeki virgül tuşu kullanıldığından gerek duymadım. Ki zaten geliştirilebilir diye not düştüm
v = StringVar()
e = Entry(master, textvariable=v)
e.pack()
v.set(“a default value”)
s = v.get()
Bu örnekde gördüğün gibi yapabilirsin. StringVar yerine IntVar() kullanarak int değerde verebilirsin
Bu kullanıcının entry’e alfabetik karakter vermesini engellemiyor, deneyebilirsiniz:
from tkinter import *
root = Tk()
v = IntVar()
e = Entry(textvariable=v)
e.pack()
v.set("12")
root.after(10 * 1000, lambda: print(repr(v.get())))
root.mainloop()