wxPython: использование Show () и Hide () - PullRequest
1 голос
/ 01 ноября 2011

Я работаю над простой программой, которая собирает и проверяет пользовательский ввод. В дополнение к отображению окно сообщения, если введенные пользователем данные не пройдены, я также хотел бы добавить приглашение просто справа от поля ввода, сообщающего пользователю, какой тип данных требуется. Для этого я создал однорядный FlexGridSizer, состоящий из следующего:

[(wx.StaticText, «Имя»), (wx.TextCtrl, «пользовательские данные здесь»), (wx.StaticText, «Руководство по вводу»)]

При инициализации виджет «Руководство по вводу» скрыт. Если пользователь не может ввести что-либо в указанное поле, а затем нажимает кнопку ОК, я хочу, чтобы произошло три вещи

  1. Поле меняет цвет, чтобы предупредить пользователя о проблеме
  2. Виджет "Руководство по вводу" (третий в приведенном выше ряду) становится видимым
  3. Размер DialogBox автоматически изменяется, чтобы учесть видимый виджет

Пока что я могу только заставить (1) работать и ищу помощи с (2) и (3).


import wx


class Not_Empty(wx.PyValidator):

    def __init__(self):
        wx.PyValidator.__init__(self)

    def Clone(self):

        return Not_Empty()

    ################################################################################
    def Validate(self, win):
        """"""
        evt_location = self.GetWindow()
        val = evt_location.GetValue()

        if val == "":
            evt_location.SetBackgroundColour(wx.Color(250,200,230))
            MyDialog().nameWarning_ST.Show(True)
            return False

        else:
            return True
    ################################################################################

    def TransferToWindow(self):
        return True

    def TransferFromWindow(self):
        return True

class MyDialog(wx.Dialog):
    def __init__(self):
        wx.Dialog.__init__(self, parent=None, id=-1, title="Getting Input", style=wx.DEFAULT_DIALOG_STYLE | wx.RESIZE_BORDER)


        # Create field labels
        name = wx.StaticText(self, -1, "Name")

        # Create user-input widgets
        name_TC = wx.TextCtrl(self, validator=Not_Empty())

        # Create and hide warning boxes
        self.nameWarning_ST = wx.StaticText(self, label="Field cannot be left empty", name="emptyAlert")

        # to see what I want the dialog to look like AFTER the user has entered an
        # empty string change 'False' to 'True' in the line below.
        self.nameWarning_ST.Show(False)

        # Create accept/cancel buttons
        btns = self.CreateButtonSizer(flags=wx.OK|wx.CANCEL)

        self.mainSizer = wx.BoxSizer(wx.VERTICAL)

        fgs = wx.FlexGridSizer(cols = 3, rows = 1)

        fgs.AddMany([(name, -1, wx.ALL, 5), (name_TC, -1, wx.ALL, 5), (self.nameWarning_ST, -1, wx.ALL, 5)])

        self.mainSizer.AddMany([(fgs, 1, wx.ALL, 0), (btns, 1, wx.ALL|wx.EXPAND, 5)])

        self.SetSizer(self.mainSizer)       
        self.mainSizer.Fit(self)

if __name__ == '__main__':

    app = wx.App() 
    dlg = MyDialog()
    dlg.Center()
    dlg.ShowModal()
    dlg.Destroy()

    app.MainLoop()

1 Ответ

3 голосов
/ 01 ноября 2011

РЕДАКТИРОВАТЬ: Для нового вопроса (ов), я бы использовал pubsub для решения этой проблемы. Поместите слушателя в инициализацию класса MyDialog, а затем опубликуйте ему сообщение, когда метод Validate будет запущен в другом классе. В обработчике сообщений, который вы теоретически создадите в MyDialog, вы захотите показать другой виджет и вызвать Layout () в диалоговом окне. Это должно привести к соответствующему изменению размера.

Вы можете прочитать учебник на pubsub здесь: http://www.blog.pythonlibrary.org/2010/06/27/wxpython-and-pubsub-a-simple-tutorial/

Для исходного вопроса было следующее:

Ваш метод Validate никогда не срабатывает, поэтому я переставил ваши методы Validate и OnChar так, чтобы они выглядели следующим образом:

import string
def Validate(self, win):
    """
    Enter your code here...
    """
    return True


def OnChar(self, event):
    txtObj = event.GetEventObject()
    txt = txtObj.GetValue()
    if txt == "": txt = '0'
    key = chr(event.GetKeyCode())

    if key in string.digits:
        if int(txt+str(key)) < 150:
            event.Skip()
        else:
            msg = "You have entered an age greater than 150!"
            wx.MessageBox(msg, "Improbable entry", style=wx.OK|wx.ICON_ERROR)

            # PROBLEM ARISES HERE
            # ===================
            MyDialog().ageWarning_ST.Show()
            MyDialog().mainSizer.Fit(MyDialog())

            return False

    key = event.GetKeyCode()
    if key in(wx.WXK_RETURN, wx.WXK_DELETE, wx.WXK_BACK):
        event.Skip()

    elif (chr(key)).isdigit():
        event.Skip()
    else:
        return

Также обратите внимание, что я импортировал строковый модуль для упрощения работы. Код, вероятно, нуждается в некоторой очистке, но он работал на моей машине.

...