Почему каретка исчезает из виджета TextCtrl после события фокуса? - PullRequest
1 голос
/ 11 июня 2019

Я пишу приложение калькулятора в MS Windows 8.1, используя wxPython-Phoenix, в котором я хотел бы, чтобы вычисление выполнялось, как только пользователь вводит значение в одно из полей параметров. Чтобы добиться этого, я использую wx.EVT_KILL_FOCUS, сгенерированное любым полем параметра, чтобы сгенерировать командное событие, которое запускает метод вычисления. Все отлично работает, кроме появления каретки в полях параметров (реализовано виджетами TextCtrl).

После установки фокуса либо клавишей Tab, либо мышью на определенном поле и перемещением его (снова клавишей Tab или мышью) в другое поле - каретка исчезла из виджета TextCtrl, который никогда не вернется! при вызове метода GetCaret () для этого виджета TextCtrl возвращаемое значение равно None.

См. Прикрепленный пример. Виджет по-прежнему принимает ввод и отображает его, но без каретки.

Как я могу восстановить каретку в правильном положении? или не потерять его в первую очередь?

Я попытался установить новую карету в TextCtrl, но она не соответствует вводу текста. Поскольку приложение должно быть сильно интерактивным, я хочу, чтобы инициирующее событие было потеряно в фокусе, а не кнопка (чтобы минимизировать количество нажатий)

import wx

class MyFrame(wx.Frame):

    def __init__(self, *args, **kwargs):
        super(MyFrame, self).__init__(*args, **kwargs)

        self.InitUI()

    def InitUI(self):
        # setting up the Input panel
        panel = wx.Panel(self)
        self.lbl1 = wx.StaticText(panel,wx.ID_ANY,'Some Text:')
        self.txt1 = wx.TextCtrl(panel,wx.ID_ANY,style=wx.TE_RIGHT)
        self.lbl2 = wx.StaticText(panel,wx.ID_ANY,'Some Other Text:')
        self.txt2 = wx.TextCtrl(panel,wx.ID_ANY,style=wx.TE_RIGHT)
        infgsz = wx.FlexGridSizer(2,2,15,15)
        infgsz.AddMany([(self.lbl1,0,wx.ALIGN_LEFT),\ 
                     (self.txt1,0,wx.ALIGN_LEFT),\
                     (self.lbl2,0,wx.ALIGN_LEFT),\ 
                     (self.txt2,0,wx.ALIGN_LEFT)])
        self.txt1.Bind(wx.EVT_KILL_FOCUS,self.OnInput)
        self.txt2.Bind(wx.EVT_KILL_FOCUS,self.OnInput)
        box = wx.BoxSizer(wx.HORIZONTAL)
        box.Add(infgsz, flag= wx.EXPAND | wx.ALL, border=15)
        panel.SetSizer(box)
        self.SetSize((280, 140))
        self.SetTitle('TextCtrl Demo')
        self.Centre()

    def OnInput(self, e):
        if e.GetId() == self.txt1.GetId():
            self.lbl2.SetForegroundColour(wx.ColourDatabase().Find('RED'))
            self.lbl1.SetForegroundColour(wx.ColourDatabase().Find('BLACK'))
        else:
            self.lbl1.SetForegroundColour(wx.ColourDatabase().Find('BLUE'))
            self.lbl2.SetForegroundColour(wx.ColourDatabase().Find('BLACK'))
        self.Refresh()

def main():
    app = wx.App()
    frame = MyFrame(None)
    frame.Show()
    app.MainLoop()

if __name__ == '__main__':
    main()

Приведенное выше приложение отображает 2 строки текста. В каждой строке есть метка (wx.StaticText виджет) слева и виджет TextCtrl справа. когда вы вводите текст в виджет TextCtrl любой строки и перемещаете фокус на другой виджет TextCtrl, соответствующий цвет переднего плана надписи (цвет текста) меняется на КРАСНЫЙ или СИНИЙ, а другая метка меняется на ЧЕРНЫЙ. Однако без видимой причины каретка исчезает из верхнего виджета TextCtrl и никогда не возвращается к нему! (На MS Windows 8.1 как минимум).

1 Ответ

1 голос
/ 11 июня 2019

Документация явно говорит вам

Обработчики событий фокуса должны почти всегда вызывать wxEvent :: Skip () в своем аргументе события, чтобы разрешить обработку по умолчанию.

и продолжает объяснять, что невыполнение этого может привести к различным проблемам - таким, как та, которую вы наблюдаете.

Добавьте e.Skip() в обработчик событий, чтобы исправить это.

...