Несколько дополнений вместо одного [gtk2hs] - PullRequest
2 голосов
/ 23 февраля 2012

У меня есть другая проблема, которую я не могу решить

У меня есть следующий код, который добавляет пользователя (имя, фамилию и возраст) в древовидную структуру.Все это работает хорошо, за исключением одной маленькой вещи: она работает хорошо только при первом добавлении пользователя.Когда вы нажимаете кнопку «Добавить», а затем пытаетесь добавить еще одного пользователя, он пытается добавить 2 пользователей, затем 3, 4 и т. Д., Увеличиваясь с каждым добавлением.Вот код, который перехватывает событие нажатия:

onClicked (dodajUczBt gui) (dodajUcz gui dbh stores)

, а вот функция dodajUcz, которая обрабатывает щелчок:

dodajUcz gui dbh stores =
    do  entrySetText (nImie gui) ""
        entrySetText (nNazwisko gui) ""
        entrySetText (nWiek gui) ""
        onClicked (cancelAddUczBt gui) (widgetHide (dodajUzDialog gui))
        onClicked (zapiszUczBtn gui) procADD
        windowPresent (dodajUzDialog gui)
    where procADD = do
            ucz <- getUczestnik
            let store = uczestnicy stores
            New.listStoreAppend store ucz
            dlugosc <- New.listStoreGetSize store
            labelSetText (lblLiczbaUcz gui) $ "Liczba uczestników: "++ show dlugosc 
            widgetHide (dodajUzDialog gui)
            addUser ucz dbh
          getUczestnik = do
                                imie <- entryGetText (nImie gui)
                                nazwisko <- entryGetText (nNazwisko gui)
                                wiek <- entryGetText (nWiek gui)
                                let wiek' = read wiek :: Integer
                                return $ Uczestnik 0 imie nazwisko wiek' False

Uczestnik - это алгебраический тип данных и addUser - это функция, которая добавляет Uczestnik в базу данных.GUI также является алгебраическим типом данных GUI, который содержит все элементы GUI, созданные castToXml

Мне кажется, что widgetHide является главной проблемой, потому что даже если вы ничего не делаете(просто откройте диалоговое окно и затем закройте его) он попытается добавить 2 пользователей при следующем открытии.

Есть идеи, как решить эту проблему?Любая помощь будет принята с благодарностью:)

1 Ответ

1 голос
/ 09 марта 2012

Что ж, я понимаю, что:

  1. Чтобы снова отобразить диалоговое окно, вы вызываете dodajUcz из другого места в вашем коде.
  2. Каждый раз, когда вы добавляете пользователя,Вы скрываете диалоговое окно (и запрашиваете его повторное отображение)
  3. НАИБОЛЕЕ ВАЖНО: каждый раз, когда вы оцениваете (то есть выполняете) dodajUcz, вы устанавливаете обработчик событиядля события «Нажал» на zapiszUczBtn СНОВА (с использованием onClicked).Когда вы устанавливаете обработчик события для события, он остается там навсегда и будет выполняться каждый раз, когда событие инициируется.если вы установите его дважды, он будет выполнен дважды.В этом конкретном случае, после вызова dodajUcz дважды, обработчик события будет выполнен дважды, когда событие Clicked запускается на zapiszUczBtn.

    Использование onClicked или любого другого установщика обработчика событий не удалит предыдущие обработчикиони добавляются в стек обработчиков для этого виджета и события.

    Когда вы инициализируете графический интерфейс (когда вы его впервые создаете), установите обработчики событий только один раз в своем коде и не выполняйте этоСнова код .Вы можете передать графический интерфейс и магазины в виде аргументов procADD затем.

    Например:

    startGUI :: DBH -> IO (GUI, Stores)
    startGUI dbh = do
      gui <- giveMeGUI -- or some other function that returns a gui
      stores <- giveMeStores -- or some other function that returns the stores
      onClicked (cancelAddUczBT gui) (widgetHide (dodaUzDialog gui))
      onClicked (zapiszUczBtn gui) (procADD gui dbh stores)
      return (gui, stores)
    
    dodajUcz gui dbh stores = do
       entrySetText (nImie gui) ""
       entrySetText (nNazwisko gui) ""
       entrySetText (nWiek gui) ""
       windowPresent (dodajUzDialog gui)
    
    procADD gui dbh stores = do
       ...
    
...