I have another problem that I can't solve
I have a following code that adds a user (first name, last name and age) into a treeview. It all works well except for one small thing: it works well only when you add an user for the first time. When you hit add and then try to add yet another user it will attempt to add 2 users, then 3, 4 and so on, increasing with each addition. Here's the code that catches the click event:
onClicked (dodajUczBt gui) (dodajUcz gui dbh stores)
and here's the function dodajUcz
that handles the click:
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
is an algebraic data type and addUser
is a function that adds an Uczestnik
into database. gui is also an algebraic data type GUI
,that holds all the gui elements created by castToXml
It seems to me that widgetHide
is the main problem, because even if you don't do anything (just open the dialog and then close it) it'll try to add 2 users the next time you open it.
Any ideas how to solve this problem? Any help would be greatly appreciated :)
Well, my understanding is that:
dodajUcz
from somewhere else in you code.MOST IMPORTANTLY: every time you evaluate (that is, execute) dodajUcz
, you install the event handler for the event 'Clicked' on zapiszUczBtn
AGAIN (using onClicked
). When you install an event handler for an event, it stays there forever and will get executed every time the event is triggered. if you install it twice, it'll get executed twice. In this particular case, after calling dodajUcz
twice, the event handler will get executed twice when the event Clicked is triggered on zapiszUczBtn
.
Using onClicked or any other event handler installer won't remove previous handlers, they get added to the handler stack for that widget and event.
When you initialise the gui (when you first create it), set the event handlers only once in your code and do not execute that code again. You can pass the gui and the stores as args to procADD
then.
For instance:
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
...