In my quiz app, the toggle buttons are used as options to get the answer from the user. But whenever a toggle button is clicked, it is in a 'down' state for the next question, but whenever I unclick that button, the next question appears, and I am missing to answer that question. I want that whenever a new question appears the state of all toggle buttons should be 'normal'. here is the code for main file:
import json
from kivy.uix.boxlayout import BoxLayout
from kivy.app import App
a=0
score=0
sca=0
class MyLayout(BoxLayout):
global data
f=open('questions.json')
data=json.load(f)
def openquestion(self):
global a
try:
self.ids.ques.text=data['category1']['question'][a]
self.ids.opt1.text=data['category1']['options'][a][0]
self.ids.opt2.text=data['category1']['options'][a][1]
self.ids.opt3.text=data['category1']['options'][a][2]
self.ids.opt4.text=data['category1']['options'][a][3]
a+=1
except:
print('all questions completed')
def checkscore(self,bu_id):
global score
global sca
answer=data['category1']['answer'][sca]
if(bu_id==answer):
score+=1
print('score: ',score,'question: ',sca+1,'button pressed: ',bu_id,'answer no:',answer)
sca+=1
class rough(App):
def build(self):
return MyLayout()
if __name__=='__main__':
rough().run()
here is the .kv file:
#:kivy 2.1.0
<QLabel@Label>:
halign:'center'
text_size:self.width,None
<ToggleButton>:
size:0.6,0.4
<MyLayout>:
orientation:'vertical'
size:root.width,root.height
padding:20
spacing:10
BoxLayout:
orientation:'vertical'
size:root.width,root.height
padding:20
spacing:10
BoxLayout:
id:options
orientation:'vertical'
spacing:7
QLabel:
id:ques
text:'Questions coming soon...'
ToggleButton:
group:options
id:opt1
text:'option01'
on_press:
root.checkscore(1)
root.openquestion()
ToggleButton:
group:options
id:opt2
text:'option02'
on_press:
root.checkscore(2)
root.openquestion()
ToggleButton:
group:options
id:opt3
text:'option03'
on_press:
root.checkscore(3)
root.openquestion()
ToggleButton:
group:options
id:opt4
text:'option04'
on_press:
root.openquestion()
root.checkscore(4)
GridLayout:
cols:2
spacing:30
Button:
text:'Next'
on_release:
root.openquestion()
Button:
text:'Exit'
on_release:
exit()
I don't think there is any need for JSON file, please just assume that there are some questions and answers for the same.
If you want the state
of all the ToggleButtons
to be normal
when a question is opened, then add code to set their states to normal
in your openquestion()
method. Also, note that on_press
is triggered whenever you click on a ToggleButton
. If you want the action to depend on whether the state
is down
or normal
, then you need to put that logic in the code that gets triggered. So, in your openquestion()
method you can add a line for each ToggleButton
like:
self.ids.opt1.state = 'normal'
Then remove the root.openquestion()
from each on_press:
of the ToggleButtons
.
The logic for opening a new question can then be added to the checkscore()
method. Something like:
def checkscore(self, bu_id):
global score
global sca
answer = data['category1']['answer'][sca]
if (bu_id == answer):
score += 1
print('score: ', score, 'question: ', sca + 1, 'button pressed: ', bu_id, 'answer no:', answer)
sca += 1
Clock.schedule_once(self.openquestion, 1)
I added the delay, using Clock.schedule_once()
, so that the user will notice the change. You could also add a Popup
or something to notify the user of whether the question was answered correctly or not. Using the Clock.schedule_once()
requires a small change to the openquestion()
signature:
def openquestion(self, *args):