هل من الممكن تقييد TextCtrl لقبول الأرقام فقط في Wxpython؟
سؤال
أريد أن أحصل على عنصر تحكم نص يقبل فقط الأرقام. (فقط قيم عدد صحيح مثل 45 أو 366)
ما هي أفضل طريقة للقيام بذلك؟
المحلول
IntCtrl
, Masked Edit Control
, ، و NumCtrl
كلها مصممة للقيام بذلك فقط ، مع مستويات مختلفة من التحكم. الخروج عن العرض التجريبي WX تحت "المزيد من النوافذ/عناصر التحكم" لمعرفة كيفية عملها.
(أو ، إذا كنت تتطلع حقًا إلى القيام بذلك مباشرة باستخدام TextCtrl الخام ، أعتقد أنك تريد التقاط أحداث EVT_CHAR ، واختبار الأحرف ، واستدعاء evt.skip () إذا كانت شخصية مسموح بها.)
نصائح أخرى
كان علي أن أفعل شيئًا مشابهًا ، والتحقق من الرموز الأبجدية الرقمية. كانت النصيحة على evt_char هي الشيء الصحيح:
class TestPanel(wx.Panel):
def __init__(self, parent):
wx.Panel.__init__(self, parent, -1)
self.entry = wx.TextCtrl(self, -1)
self.entry.Bind(wx.EVT_CHAR, self.handle_keypress)
def handle_keypress(self, event):
keycode = event.GetKeyCode()
if keycode < 255:
# valid ASCII
if chr(keycode).isalnum():
# Valid alphanumeric character
event.Skip()
يمكنك المحاولة IntCtrl
, EVT_CHAR
, أو تنفيذ مدقق جديد/موجود (مثل Intvalidator). يمكن استخدام المدققات للتحقق من صحة حقل (مفيد عند محاولة التحقق من صحة أشياء متعددة في مربع حوار/لوحة) ويمكن أيضًا استخدامها مع EVT_CHAR لتقييد الإدخال في حقل.
كما يلاحظ الإجابات الأخرى ، من الممكن القيام بذلك باستخدام EVT_CHAR
معالج. سترغب في الاتصال event.Skip()
بالنسبة للشخصيات التي تريد السماح بها ، ولا تسميها لتلك التي تريد حظرها. واحد فارغ هو أنك ربما تريد الاتصال أيضًا event.Skip()
لأحرف TAB ؛ يضغط الضغط على علامة التبويب EVT_CHAR
الحدث ، وإذا لم تتصل event.Skip()
, ، سوف تقوم بتعطيل عملية اجتياز علامة التبويب بشكل فعال بين TextCtrl
س.
إليك تطبيق أدنى يوضح اثنين TextCtrl
S التي تقبل عدد صحيح أو أرقام عشرية ، مع عبور علامات التبويب العمل:
import wx
app = wx.App()
frame = wx.Frame(None, -1, 'simple.py')
panel = wx.Panel(frame)
text_ctrl_1 = wx.TextCtrl(panel, value='123')
text_ctrl_2 = wx.TextCtrl(panel, value='456', pos=(0, 30))
def block_non_numbers(event):
key_code = event.GetKeyCode()
# Allow ASCII numerics
if ord('0') <= key_code <= ord('9'):
event.Skip()
return
# Allow decimal points
if key_code == ord('.'):
event.Skip()
return
# Allow tabs, for tab navigation between TextCtrls
if key_code == ord('\t'):
event.Skip()
return
# Block everything else
return
text_ctrl_1.Bind(wx.EVT_CHAR, block_non_numbers)
text_ctrl_2.Bind(wx.EVT_CHAR, block_non_numbers)
frame.Show()
app.MainLoop()
Numctrl لديه بعض المراوغات الغريبة بالنسبة لي. فيما يلي محاولتي لإنشاء عنصر تحكم في الأرقام يعتمد على EVT_CHAR و KEYCODE.
يتيح عنصر التحكم هذا الأرقام بالإضافة إلى جميع الرمز الرئيسي الخاص (CTRL Combo ، مفتاح السهم ، Space ، إلخ ...) ، بحيث لا يزال هناك نسخ من الصغار ، التراجع عن ذلك ، Select-All وما إلى ذلك. سوف يحظر فقط الأحرف الأخرى القابلة للطباعة (باستخدام string.printable) وأحرف يونيكود (باستخدام WXK_NONE)
يمكن العثور على طريقة أخرى للتحقق والسماح لجميع الرمز الرئيسي الخاص هذا الجواب. هذا نهج أفضل ولكنه يتطلب المزيد من التعليمات البرمجية.
import string
MyNumCtrl = wx.TextCtrl()
MyNumCtrl.Bind(EVT_CHAR, onChar)
def onChar(self, event):
keycode = event.GetKeyCode()
obj = event.GetEventObject()
val = obj.GetValue()
# filter unicode characters
if keycode == wx.WXK_NONE:
pass
# allow digits
elif chr(keycode) in string.digits:
event.Skip()
# allow special, non-printable keycodes
elif chr(keycode) not in string.printable:
event.Skip() # allow all other special keycode
# allow '-' for negative numbers
elif chr(keycode) == '-':
if val[0] == '-':
obj.SetValue(val[1:])
else:
obj.SetValue('-' + val)
# allow '.' for float numbers
elif chr(keycode) == '.' and '.' not in val:
event.Skip()
return
يرجى التحقق من البرنامج النصي "Valitator.py" في Wxpython Demo. إنه بالضبط ما تحتاجه