Python 2.7 wxPython:是否从绑定到EVT_文本的TextCtrl中排除关键事件?
我正在编写一个小通讯录,它有很多输入字段和一个sqlite数据库,有点高级。 总之,我的输入主窗口包含许多用于db表列的textctrl字段。 我制作了一个小演示,它反映了是否显示了人员数据:Python 2.7 wxPython:是否从绑定到EVT_文本的TextCtrl中排除关键事件?,python-2.7,wxpython,wx.textctrl,Python 2.7,Wxpython,Wx.textctrl,我正在编写一个小通讯录,它有很多输入字段和一个sqlite数据库,有点高级。 总之,我的输入主窗口包含许多用于db表列的textctrl字段。 我制作了一个小演示,它反映了是否显示了人员数据: # -*- encoding: utf-8 -*- import wx class MyWindow(wx.Frame): def __init__(self, parent): noResize_frameStyle = wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.C
# -*- encoding: utf-8 -*-
import wx
class MyWindow(wx.Frame):
def __init__(self, parent):
noResize_frameStyle = wx.SYSTEM_MENU | wx.CLOSE_BOX | wx.CAPTION
wx.Frame.__init__(self, parent, -1, title='DEMO', pos=(300, 100),
size=(150, 200), style=noResize_frameStyle)
# Panel
self.panel = wx.Panel(self)
# Input Fields
self.input_1 = wx.TextCtrl(self.panel, size=wx.Size(150, 22), style=wx.TE_PROCESS_ENTER)
self.input_2 = wx.TextCtrl(self.panel, size=wx.Size(150, 22), style=wx.TE_PROCESS_ENTER)
self.input_3 = wx.TextCtrl(self.panel, size=wx.Size(150, 22), style=wx.TE_PROCESS_ENTER)
self.input_4 = wx.TextCtrl(self.panel, size=wx.Size(150, 40), style=wx.TE_MULTILINE | wx.TE_NO_VSCROLL | wx.TE_PROCESS_ENTER)
self.input_4.evt_run = 0
self.il = input_list = [self.input_1, self.input_2, self.input_3, self.input_4]
# Buttons
self.button_1 = wx.Button(self.panel, label='Clear')
self.button_2 = wx.Button(self.panel, label='Add Stuff')
# Binds:
for entry in input_list:
entry.string = ''
entry.Bind(wx.EVT_TEXT, self.OnEdit)
entry.Bind(wx.EVT_TEXT_ENTER, self.OnEnter)
self.button_1.Bind(wx.EVT_BUTTON, self.OnClear)
self.button_2.Bind(wx.EVT_BUTTON, self.OnAddStuff)
# Sizer
self.sizer_v = wx.BoxSizer(wx.VERTICAL)
for entry in input_list:
self.sizer_v.Add(entry, 0)
self.sizer_v.Add(self.button_1, 0)
self.sizer_v.Add(self.button_2, 0)
# Set Sizer
self.panel.SetSizerAndFit(self.sizer_v)
def OnClear(self, event):
for entry in self.il:
entry.ChangeValue('')
entry.string = ''
entry.SetBackgroundColour("White")
def OnAddStuff(self, event):
string_list = ['Hello', 'World', 'and', 'the whole\nUniverse' ]
for i,entry in enumerate(self.il):
entry.ChangeValue(string_list[i])
entry.string = string_list[i]
entry.SetBackgroundColour("White")
def compare(self, object):
# Check if it has been modified
if object.GetValue() == object.string:
return 1
else:
return 0
#if object.IsModified():
# return 0
#else:
# return 1
def OnEdit(self, events):
object = events.GetEventObject()
if self.compare(object):
print 'is the same'
object.SetBackgroundColour("White")
else:
print 'not the same anymore'
object.SetBackgroundColour("yellow")
self.Refresh()
def OnEnter(self, events):
object = events.GetEventObject()
# Ignore first ENTER if MultiLine
if object.IsMultiLine():
if object.evt_run == 0:
object.evt_run = + 1
return
else:
object.evt_run = 0
if self.compare(object):
return
result = object.GetValue()
object.string = result
print result
object.SetBackgroundColour("Green")
self.Refresh()
class MyApp(wx.App):
def OnInit(self):
frame = MyWindow(None)
frame.Show(True)
return True
app = MyApp(0)
app.MainLoop()
我将这些输入字段绑定到wx事件EVT_文本以及EVT_文本输入。第一个调用函数OnEdit,第二个调用函数OnEnter。按“添加内容”按钮反映加载了人员数据。
现在编辑一个字段将导致黄色背景,如果它与从DB获得的值不同
我知道有isModified()用于执行此操作,但这一个不会检测它是否再次相同,并且也会对CTRL+A作出反应,这不是我要找的。因此,我将数据库中的字符串数据添加到textctrl以及.string属性以进行比较
如果在编辑的字段上按enter键,它会将结果写入数据库,调用ChangeValue并将背景变为绿色。(计划在将来仅临时使用计时器执行此操作)
我的问题是我的数据库中有多行字段,我也为这个演示添加了一个。您可以看到我的解决方法,它将忽略第一次输入而不写入结果
这是可行的,但解决方案不是很好
您总是会听到恼人的叮当声(至少在windows上),出于某种原因,EVT_文本事件als会检测到第二次回车并运行OnChange函数,该函数会立即再次将背景变为白色
有办法解决这个问题吗?是否可以在my OnEdit函数中排除忽略Enter键的KEY_事件?
也许有更好的方法来实现同样的目标
谢谢你的帮助
我的数据库数据是UTF-8
Python:2.7.9
wxPython:3.0.2.0没有解决方案,只有一些建议。我建议对事物进行更好的命名,例如self.butClear或类似的东西。要加载和清除字段,您可以使用validator.TransferToWindows和validator.TransferFromWindow,例如,请参阅示例项目MediaLocker-通过将内容与数据库进行比较,您希望实现什么?您只想在db中更改实际更改还是…?是的,如果从db加载了人员数据,则会将所有输入字段设置为正确的值(名称、地址…)以及用于比较的字符串属性。。我的想法是向用户显示他是否编辑了一个字段,以颜色提醒他该字段现在已从数据库中更改,如果他按enter键,更改将提交到数据库,并通知用户其更改现在已保存。我把上面的代码精简到问题的最低限度。每个输入字段都有一个具有db列名的属性,用于将更改添加到正确的db列中