2

我还有一个无法解决的问题

我有以下代码将用户(名字、姓氏和年龄)添加到树视图中。除了一件小事之外,一切都很好:只有当您第一次添加用户时它才能正常工作。当您点击添加然后尝试添加另一个用户时,它将尝试添加 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 创建的所有 gui 元素castToXml

在我看来,这widgetHide是主要问题,因为即使您什么都不做(只需打开对话框然后关闭它),它会在您下次打开它时尝试添加 2 个用户。

任何想法如何解决这个问题?任何帮助将不胜感激 :)

4

1 回答 1

1

嗯,我的理解是:

  1. 要再次显示对话框,请dodajUcz从代码中的其他位置调用。
  2. 每次添加用户时,都会隐藏对话框(并要求再次显示)
  3. 最重要的是:每次评估(即执行)时,您都会在AGAINdodajUcz上安装事件“Clicked”的事件处理程序(使用)。当您为事件安装事件处理程序时,它会永远保留在那里,并且每次触发事件时都会执行。如果你安装它两次,它将被执行两次。在这种特殊情况下,调用两次后,事件处理程序将在触发事件 Clicked 时执行两次。zapiszUczBtn onClickeddodajUczzapiszUczBtn

    使用 onClicked 或任何其他事件处理程序安装程序不会删除以前的处理程序,它们会被添加到该小部件和事件的处理程序堆栈中。

    当您初始化 gui 时(当您第一次创建它时),在您的代码中只设置一次事件处理程序并且不要再次执行该代码。您可以将 gui 和商店作为参数传递给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
       ...
    
于 2012-03-09T02:11:23.667 回答