Exemple #1
0
    def __init__(self, block_num, device, temperature, settings, widgets=None):
        super().__init__(block_num, device, temperature, settings, widgets)
        # load settings from external TOML
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        # load images
        img_names = ['dv7_%i.png' % i for i in range(1, 8, 1)]
        self.img_names = [
            os.path.join(settings['translation_dir'], '%s/%s' % (lang, x))
            for x in img_names
        ]
        random.shuffle(self.img_names)

        self.prompt = translation['prompt'][lang]
        self.prompt2 = translation['prompt2'][lang]
        header = ['A', 'B']
        question = translation['question'][lang]
        self.qs = []
        self.questions = []
        # GUI stuff
        widgets = []
        widgets.append(JustText(self.prompt))
        for img in self.img_names:
            widgets.append(PerceptualQuestion(img, header, question))
            self.questions.append(question)
            self.qs.append(
                widgets[-1]
            )  # keep questions in separate list of easy checking

        widgets.insert(2, JustText(self.prompt2))
        self.add_widgets(widgets)
    def __init__(self, prompt, headers, n_elements=6):
        super().__init__()
        layout2 = qtw.QVBoxLayout()

        grid_wid = qtw.QWidget()
        layout = qtw.QGridLayout()
        layout.addWidget(JustText(headers[0]), 0, 0, Qt.AlignCenter)
        layout.addWidget(JustText(headers[1]), 0, 1, Qt.AlignCenter)
        validator = QIntValidator(1, 1000)
        self.groups = []
        self.nums = []
        for i in range(n_elements):
            group_name = qtw.QLineEdit()
            group_name.setMaximumWidth(200)
            fnt = group_name.font()
            fnt.setPointSize(26)
            group_name.setFont(fnt)
            num_people = qtw.QLineEdit()
            num_people.setMaximumWidth(200)
            num_people.setFont(fnt)
            num_people.setValidator(validator)
            self.groups.append(group_name)
            self.nums.append(num_people)
            layout.addWidget(group_name, i + 1, 0, Qt.AlignCenter)
            layout.addWidget(num_people, i + 1, 1, Qt.AlignCenter)

        grid_wid.setLayout(layout)
        layout2.addWidget(JustText(prompt))
        layout2.addWidget(grid_wid)
        self.setLayout(layout2)
Exemple #3
0
    def __init__(self, device, settings):
        super().__init__(-1, device, 0, settings, None)
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'], '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        working = JustText(translation['confirm'][lang])
        continuing = JustText(translation['continue'][lang])

        self.add_widgets([working, continuing])
Exemple #4
0
    def __init__(self, device, settings):
        super().__init__(-1, device, 0, settings, None)
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'], '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        sec1 = JustText(translation['sec1'][lang])
        sec2 = JustText(translation['sec2'][lang])

        self.q = ComfortQuestion('', translation['q1_header'][lang], translation['q1'][lang])
        self.qtxt = translation['q1'][lang]

        self.add_widgets([sec1, sec2, self.q])
Exemple #5
0
    def __init__(self, block_num, device, temperature, settings, widgets=None):
        super().__init__(block_num, device, temperature, settings, widgets)
        # load settings from external TOML
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        prompt = translation['prompt'][lang]
        header1 = translation['header1'][lang]
        header2 = translation['header2'][lang]
        q1 = translation['question1'][lang]
        q2 = translation['question2'][lang]
        q3 = translation['question3'][lang]

        # excludes the default (none) response
        answers = [t[lang] for t in translation['ans']]
        answers.insert(0, '')

        movie_txt = [m[lang] for m in translation['movie']]
        random.shuffle(movie_txt)

        widgets = []
        self.qs = []
        self.movs = []
        widgets.append(JustText(prompt))
        for mov in movie_txt:
            self.movs.extend([mov] * 3)
            self.qs.extend([q1, q2, q3])
            widgets.append(
                MovieQuestion([header1, header2], [q1, q2, q3], answers, mov))
        self.add_widgets(widgets)
Exemple #6
0
 def __init__(self, img_name, questions):
     super().__init__()
     layout = qtw.QVBoxLayout()
     img = QPixmap(img_name)
     img_holder = qtw.QLabel()
     img_holder.setPixmap(img.scaled(800, 500, Qt.KeepAspectRatio, Qt.SmoothTransformation))
     img_holder.setAlignment(Qt.AlignCenter)
     self.edit_boxes = []
     layout.addWidget(img_holder)
     for q in questions:
         wid = qtw.QWidget()
         hlay = qtw.QHBoxLayout()
         txt = JustText(q)
         ebox = qtw.QLineEdit()
         # not sure how many digits to allow depending on currency
         ebox.setValidator(QDoubleValidator(0, 10000, 2))
         ebox.setMaximumWidth(200)
         fnt = ebox.font()
         fnt.setPointSize(26)
         ebox.setFont(fnt)
         ebox.setStyleSheet('QLineEdit {background-color: yellow; border: 2px solid gray;}')
         self.edit_boxes.append(ebox)
         hlay.addWidget(txt, Qt.AlignRight | Qt.AlignVCenter)
         hlay.addWidget(ebox, Qt.AlignLeft | Qt.AlignVCenter)
         wid.setLayout(hlay)
         layout.addWidget(wid)
     self.setLayout(layout)
Exemple #7
0
    def __init__(self, block_num, device, temperature, settings, widgets=None):
        super().__init__(block_num, device, temperature, settings, widgets)
        # load settings from external TOML
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        prompt = translation['prompt'][lang]
        header = translation['header'][lang]

        # questions
        self.questions = [
            ('q%i' % i, pr[lang], q[lang]) for i, (pr, q) in enumerate(
                zip(translation['subprompt'], translation['question']))
        ]

        # new ordering
        random.shuffle(self.questions)

        prompt = JustText(prompt)
        widgets = []
        widgets.append(prompt)
        for question in self.questions:
            widgets.append(
                UtilitarianQuestion(question[1], header, question[2]))
        self.add_widgets(widgets)
Exemple #8
0
    def __init__(self, block_num, device, temperature, settings, widgets=None):
        super().__init__(block_num, device, temperature, settings, widgets)
        # load settings from external TOML
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        # load images
        img_names = ['dv6_%i.png' % i for i in range(1, 9, 1)]
        self.img_names = [
            resource_filename('embr_survey', 'images/%s' % img)
            for img in img_names
        ]
        random.shuffle(self.img_names)

        prompt = translation['prompt'][lang]
        header = translation['header'][lang]
        qtext = [q[lang] for q in translation['question']]

        widgets = []
        widgets.append(JustText(prompt))
        self.questions = []
        for img in self.img_names:
            self.questions.extend(qtext)
            widgets.append(CriminalQuestion(img, header, qtext))
        self.add_widgets(
            widgets)  # add_widgets also adds to internal list `self.widgets`
    def __init__(self, block_num, device, temperature, settings, widgets=None):
        super().__init__(block_num, device, temperature, settings, widgets)
        # load settings from external TOML
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        translation = {k: translation[k][lang] for k in translation.keys()}

        # pg 1
        self.q_purpose = TextInput(translation['q_purpose'])
        # pg 2
        self.q_related = RadioGroupQ(translation['q_related'],
                                     translation['q_related_ans'])
        #
        self.q_related_how = TextInput(translation['q_how'])
        #
        self.q_influence = RadioGroupQ(translation['q_influence'],
                                       translation['q_related_ans'])
        #
        self.q_how_influence = TextInput(translation['q_how_influence'])
        #
        self.fin = JustText(translation['fin'])
        self.q_data = RadioGroupQ('', translation['q_related_ans'][:2])
        self.fin2 = JustText(translation['fin2'])

        wid = qtw.QWidget()
        lyt = qtw.QVBoxLayout()
        lyt.addWidget(self.fin)
        lyt.addWidget(self.q_data)
        lyt.addWidget(self.fin2)
        wid.setLayout(lyt)

        self.add_widgets([
            self.q_purpose, self.q_related, self.q_related_how,
            self.q_influence, self.q_how_influence, wid
        ])

        self.qs = [
            translation[x] for x in [
                'q_purpose', 'q_related', 'q_how', 'q_influence',
                'q_how_influence'
            ]
        ]
        self.qs.append('save data?')
Exemple #10
0
 def __init__(self, prompt, header, question):
     super().__init__()
     txt = JustText(prompt)
     self.question = SingleQuestion(header, question)
     layout = qtw.QVBoxLayout()
     layout.addWidget(txt)
     layout.addWidget(self.question)
     self.setLayout(layout)
Exemple #11
0
 def __init__(self, headers, questions, q3_ans, movie_info):
     super().__init__()
     self.question1 = SingleQuestion(headers[0], questions[0])
     self.question2 = SingleQuestion(headers[1], questions[1])
     self.question3 = DropDownQuestion(questions[2], q3_ans)
     layout = qtw.QVBoxLayout()
     layout.addWidget(JustText(movie_info))
     layout.addWidget(self.question1)
     layout.addWidget(self.question2)
     layout.addWidget(self.question3)
     self.setLayout(layout)
 def __init__(self, prompt):
     super().__init__()
     prompt = JustText(prompt)
     layout = qtw.QVBoxLayout()
     layout.addWidget(prompt, alignment=Qt.AlignVCenter)
     self.name_input = qtw.QLineEdit()
     self.name_input.setMaximumWidth(800)
     fnt = self.name_input.font()
     fnt.setPointSize(26)
     self.name_input.setFont(fnt)
     layout.addWidget(self.name_input, alignment=Qt.AlignVCenter)
     self.setLayout(layout)
Exemple #13
0
 def __init__(self, question, answers):
     super().__init__()
     layout = qtw.QHBoxLayout()
     q = JustText(question)
     self.answer = qtw.QComboBox()
     fnt = self.answer.font()
     fnt.setPointSize(26)
     self.answer.setFont(fnt)
     self.answer.addItems(answers)
     self._default_ans = answers[0]
     layout.addWidget(q, Qt.AlignRight | Qt.AlignVCenter)
     layout.addWidget(self.answer, Qt.AlignLeft | Qt.AlignCenter)
     self.setLayout(layout)
Exemple #14
0
    def __init__(self, brand, subprompt, warm, friendly, rest_header, rest_qs):
        super().__init__()
        self.warm_q = SingleQuestion(*warm)
        self.friendly_q = SingleQuestion(*friendly)
        # One MultiQuestion (same header)
        self.multi_q = MultiQuestion(rest_header, rest_qs)

        txt = JustText(subprompt % brand)  # Please answer the following...
        lt = qtw.QVBoxLayout()
        lt.addWidget(txt)
        lt.addWidget(self.warm_q)
        lt.addWidget(self.friendly_q)
        lt.addWidget(self.multi_q)
        self.setLayout(lt)
Exemple #15
0
    def __init__(self, block_num, device, temperature, settings, widgets=None):
        super().__init__(block_num, device, temperature, settings, widgets)
        # load settings from external TOML
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        prompt = translation['prompt'][lang]  # in this next section,...
        prompt2 = translation['prompt2'][
            lang]  # Please answer the following...

        warm = [translation['warm_header'][lang], translation['warm'][lang]]
        friendly = [
            translation['friendly_header'][lang], translation['friendly'][lang]
        ]

        rest_header = translation['rest_header'][lang]
        rest_qs = [
            translation[x][lang] for x in [
                'intentions', 'public_interest', 'rugged', 'competence',
                'aggressive'
            ]
        ]

        # Fixed for now
        brands = ['ADIDAS', 'NIKE', 'REEBOK']
        random.shuffle(brands)

        self.questions = []  # actual question text
        self.brand_col = []  # convenience
        widgets = []
        widgets.append(JustText(prompt))
        for brand in brands:
            widgets.append(
                ThatsMyBrand(brand, prompt2, warm, friendly, rest_header,
                             rest_qs))
            # two sets of single Qs (different header)
            # these won't end up aligning very well
            self.brand_col.extend([brand] * 7)
            self.questions.extend([warm[1], friendly[1]])
            self.questions.extend(rest_qs)

        self.add_widgets(widgets)
Exemple #16
0
    def __init__(self, block_num, device, temperature, settings):
        super().__init__(block_num, device, temperature, settings)
        lang = settings['language']

        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        prompt = translation['prompt'][lang]
        self.question = translation['question'][lang]
        header = translation['header'][lang]

        layout = qtw.QVBoxLayout()
        layout.addWidget(JustText(prompt))

        self.qs = SingleQuestion(header, self.question)
        layout.addWidget(self.qs)

        self.setLayout(layout)
 def __init__(self, text, units, device):
     super().__init__()
     self.device = device
     prompt = JustText(text)
     layout = qtw.QVBoxLayout()
     layout.addWidget(prompt, alignment=Qt.AlignVCenter)
     #self.temp_input = qtw.QSpinBox()
     self.temp_input = qtw.QComboBox()
     if units == 'C':
         minmax = (4, 43)
     elif units == 'F':
         minmax = (40, 110)
     units = '°' + units
     vals = [str(v) + units for v in range(*minmax)]
     self.temp_input.addItem('')
     self.temp_input.addItems(vals)
     fnt = self.temp_input.font()
     fnt.setPointSize(26)
     self.temp_input.setFont(fnt)
     layout.addWidget(self.temp_input, alignment=Qt.AlignVCenter)
     self.setLayout(layout)
Exemple #18
0
 def _single_shot(self):
     try:
         # connect to the device
         # blocks progression (TODO: add a note)
         if not self._is_connected:
             device = EmbrWave(self.device.currentText())
             atexit.register(device.close)
             signal.signal(signal.SIGINT, partial(handle_sig, device))
             self._is_connected = True
             self._device = device
             self.connector.setText('Connected.')
             self.connector.setStyleSheet(green_style)
             self.layout().addWidget(
                 JustText('<b>Battery level: %i</b>' %
                          device.battery_charge), 6, 0, 2, 2,
                 Qt.AlignCenter)
     except Exception as e:
         self.connector.setText(
             'Connection failed.\nTry to click again\n(or restart program)?'
         )
         self._is_connected = False
         self._log.warn(repr(e))
Exemple #19
0
 def __init__(self, text, units, device):
     super().__init__()
     self.device = device
     prompt = JustText(text)
     layout = qtw.QVBoxLayout()
     layout.addWidget(prompt, alignment=Qt.AlignVCenter)
     self.temp_input = qtw.QSpinBox()
     if units == 'C':
         minmax = (0, 100)
         default = 21
     elif units == 'F':
         minmax = (32, 212)
         default = 70
     self.temp_input.setRange(*minmax)
     self.temp_input.setSingleStep(1)
     self.temp_input.setSuffix('°' + units)
     self.temp_input.setValue(default)
     fnt = self.temp_input.font()
     fnt.setPointSize(26)
     self.temp_input.setFont(fnt)
     layout.addWidget(self.temp_input, alignment=Qt.AlignVCenter)
     self.setLayout(layout)
Exemple #20
0
    def __init__(self):
        super().__init__()
        self._window = None  # patched in later (reference to MainWindow)
        self._device = DummyWave()
        self._is_connected = False

        if not gatt_ble:
            self.pre_embr = DummyPreEmbr()
        else:
            self.pre_embr = PreEmbr()

        # id, language, locale
        self.settings = {}
        self.settings['translation_dir'] = os.path.join(
            application_path, 'translations/')
        self.settings['locale_dir'] = os.path.join(application_path, 'locale/')
        self.settings[
            'app_path'] = application_path  # allows searching relative
        # to the location of the executable
        # check all translation files, and list only complete ones

        translation_files = glob(
            os.path.join(self.settings['translation_dir'], '*.toml'))

        # figure out complete translations, using english as ref
        languages = count_language_keys(translation_files, 'en')
        # now same with localization
        # I think it's "more" ok to have missing keys in localization files,
        # and if the locale has *any* keys it should be allowed (and the default
        # subbed in if missing)
        locale_files = glob(os.path.join(self.settings['locale_dir'],
                                         '*.toml'))
        locales = check_locale_keys(locale_files, 'us')

        # translations for *this* widget
        translation_path = os.path.join(self.settings['translation_dir'],
                                        'misc.toml')
        with open(translation_path, 'r', encoding='utf8') as f:
            self.translations = toml.load(f)

        # widgets and layout
        layout = qtw.QGridLayout()

        self.id = qtw.QLineEdit()
        self.lang = qtw.QComboBox()
        fnt = self.lang.font()
        fnt.setPointSize(26)
        self.lang.setFont(fnt)
        self.lang.currentIndexChanged.connect(partial(on_activated, self))
        self.locale = qtw.QComboBox()
        self.locale.setFont(fnt)
        self.device = qtw.QComboBox()
        self.device.setFont(fnt)
        self.device.addItems(self.pre_embr.addrs)

        self.id.setFont(fnt)

        # TODO: these *also* need to be translated...
        self.id_label = JustText(self.translations['participant']['en'])
        self.lang_label = JustText(self.translations['language']['en'])
        self.locale_label = JustText(self.translations['locale']['en'])
        self.device_label = JustText('Embr Wave ID')
        self.dev_instr = JustText(self.translations['dev_instr']['en'])

        # default to english/us, which *should* exist & be complete
        self.lang.addItems(languages)
        self.lang.setCurrentText('en')
        self.locale.addItems(locales)
        self.locale.setCurrentText('us')

        self.blinker = qtw.QPushButton('Blink')
        self.blinker.clicked.connect(partial(on_blink, self))

        self.connector = qtw.QPushButton('Connect (will freeze\ntemporarily)')
        self.connector.clicked.connect(self.try_connect)

        self.blinker.setStyleSheet(base_style)
        self.connector.setStyleSheet(base_style)

        layout.addWidget(self.id_label, 0, 0, Qt.AlignCenter)
        layout.addWidget(self.id, 0, 1, Qt.AlignCenter | Qt.AlignLeft)
        layout.addWidget(self.lang_label, 1, 0, Qt.AlignCenter)
        layout.addWidget(self.lang, 1, 1, Qt.AlignCenter | Qt.AlignLeft)
        layout.addWidget(self.locale_label, 2, 0, Qt.AlignCenter)
        layout.addWidget(self.locale, 2, 1, Qt.AlignCenter | Qt.AlignLeft)
        layout.addWidget(self.device_label, 3, 0, Qt.AlignCenter)
        layout.addWidget(self.device, 3, 1, Qt.AlignCenter | Qt.AlignLeft)
        layout.addWidget(self.dev_instr, 5, 0, Qt.AlignCenter)
        layout.addWidget(self.blinker, 5, 1, Qt.AlignCenter | Qt.AlignLeft)
        layout.addWidget(self.connector, 5, 1, Qt.AlignCenter)

        self.setLayout(layout)
Exemple #21
0
    def __init__(self, block_num, device, temperature, settings):
        super().__init__(block_num, device, temperature, settings)

        lang = settings['language']
        locale = settings['locale']
        translation_path = os.path.join(settings['translation_dir'],
                                        '%s.toml' % self.name)
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        locale_path = os.path.join(settings['locale_dir'],
                                   '%s.toml' % self.name)

        with open(locale_path, 'r', encoding='utf8') as f:
            locale_settings = toml.load(f)

        # read in all images
        try:
            images = locale_settings['house_photos'][locale]
        except KeyError:
            # use default locale (US)
            images = locale_settings['house_photos']['us']
        # now handle localized image location
        for count, img in enumerate(images):
            # if locale has path specified, look relative to exe location
            if os.path.split(img)[0] != '':
                # TODO: verify this is the right pattern
                images[count] = os.path.join(application_path, img)
            else:
                # no path for locale, assume it's one of the baked-in ones
                images[count] = resource_filename('embr_survey',
                                                  'images/%s' % img)

        # read in translations, also plugging in locale-specific info
        self.prompt = translation['prompt'][lang]
        self.preprompt = translation['preprompt'][lang]
        self.big_title = translation['big_title'][lang]

        try:
            cost = locale_settings['house_cost'][locale]
        except KeyError:
            cost = locale_settings['house_cost']['us']
        self.background = translation['background'][lang] % cost
        self.subtitle = translation['subtitle'][lang]

        self.floor1 = translation['f1'][lang]
        try:
            floor_label = locale_settings['floor_label'][locale]
        except KeyError:
            floor_label = locale_settings['floor_label']['us']
        self.floor2 = translation['f2'][lang] % floor_label[0]
        self.floor3 = translation['f3'][lang] % floor_label[1]

        prompt2 = translation['prompt2'][lang]
        header = translation['header'][lang]

        self.questions = [('q%i' % i, q[lang])
                          for i, q in enumerate(translation['question'])]
        random.shuffle(self.questions)

        # now set up gui
        self.images = {os.path.basename(n): QPixmap(n) for n in images}
        for img in self.images:
            ql = qtw.QLabel()
            ql.setPixmap(self.images[img].scaled(800, 500, Qt.KeepAspectRatio,
                                                 Qt.SmoothTransformation))
            self.images[img] = ql

        layout = qtw.QVBoxLayout()
        layout.addWidget(JustText(
            self.prompt))  # next, we are going to present...
        layout.addWidget(JustText(self.preprompt))  # what do you think..
        layout.addWidget(self.images['dv5_1.png'],
                         alignment=Qt.AlignCenter)  # initial image
        layout.addWidget(JustText('<b>%s</b>' %
                                  self.big_title))  # general info
        layout.addWidget(JustText(self.background))  # General info...
        layout.addWidget(JustText(self.subtitle))  # the resale value...
        layout.addWidget(JustText(self.floor1))
        layout.addWidget(JustText(self.floor2))
        layout.addWidget(JustText(self.floor3))
        imgs = [('dv5_2.png', 'dv5_3.png'), ('dv5_4.png', 'dv5_5.png'),
                ('dv5_6.png', 'dv5_7.png'), ('dv5_8.png', 'dv5_9.png')]
        for im1, im2 in imgs:
            r1 = qtw.QHBoxLayout()
            r1.addWidget(self.images[im1])
            r1.addWidget(self.images[im2])
            w1 = qtw.QWidget()
            w1.setLayout(r1)
            layout.addWidget(w1, alignment=Qt.AlignCenter)
        layout.addWidget(self.images['dv5_10.png'], alignment=Qt.AlignCenter)
        layout.addWidget(JustText(prompt2))

        self.qs = MultiQuestion(header, [q[1] for q in self.questions])
        layout.addWidget(self.qs)
        self.setLayout(layout)
    def __init__(self, block_num, device, settings):
        super().__init__()
        lang = settings['language']
        translation_path = os.path.join(settings['translation_dir'],
                                        'individual_differences.toml')
        with open(translation_path, 'r', encoding='utf8') as f:
            translation = toml.load(f)

        # separate out the translation we care about
        translation = {k: translation[k][lang] for k in translation.keys()}
        self.translation = translation
        self.block_num = block_num
        self.settings = settings
        self.device = device  # just to disable it
        layout = qtw.QVBoxLayout()

        layout.addWidget(JustText(
            translation['instructions']))  # this questionnaire...

        self.q1 = RadioGroupQ(translation['q1'],
                              translation['q1_ans'])  # marital
        self.q2 = RadioGroupQ(translation['q2'],
                              translation['q2_ans'])  # children
        self.q2a = RadioGroupQ(translation['q2a'],
                               translation['q2_ans'])  # talk to them
        # whenever q2 is clicked, check if index is valid; if so, show q2a
        self.q2grp = ConditionalWidget(self.q2, self.q2a,
                                       translation['q2_ans'][1:])
        self.q3 = RadioGroupQ(translation['q3'], translation['q3_ans'])
        self.q3a = RadioGroupQ(translation['q3a'], translation['q3_ans'])
        self.q3grp = ConditionalWidget(self.q3, self.q3a,
                                       translation['q3_ans'][1:])
        self.q4 = RadioGroupQ(translation['q4'], translation['q4_ans'])
        self.q4a = RadioGroupQ(translation['q4a'], translation['q3_ans'])
        self.q4grp = ConditionalWidget(self.q4, self.q4a,
                                       translation['q4_ans'][1:-1])
        self.q5 = RadioGroupQ(translation['q5'], translation['q2_ans'])
        self.q5a = RadioGroupQ(translation['q5a'], translation['q2_ans'])
        self.q5grp = ConditionalWidget(self.q5, self.q5a,
                                       translation['q2_ans'][1:])
        self.q6 = RadioGroupQ(translation['q6'], translation['q2_ans'])
        self.q6a = RadioGroupQ(translation['q6a'], translation['q2_ans'])
        self.q6grp = ConditionalWidget(self.q6, self.q6a,
                                       translation['q2_ans'][1:])
        self.q7 = RadioGroupQ(translation['q7'], translation['q7_ans'])
        self.q7a = RadioGroupQ(translation['q7a'], translation['q2_ans'])
        self.q7grp = ConditionalWidget(self.q7, self.q7a,
                                       translation['q7_ans'][1])
        self.q8 = RadioGroupQ(translation['q8'], translation['q7_ans'])
        self.q8a = RadioGroupQ(translation['q8a'], translation['q2_ans'])
        self.q8grp = ConditionalWidget(self.q8, self.q8a,
                                       translation['q7_ans'][1])

        # q9 is special (*two* optional responses)
        self.q9 = RadioGroupQ(translation['q9'], translation['q9_ans'])
        self.q9a = RadioGroupQ(translation['q9a'], translation['q2_ans'])
        self.q9b = RadioGroupQ(translation['q9b'], translation['q2_ans'])
        self.q9grp = ConditionalWidget2(self.q9, self.q9a, self.q9b,
                                        translation['q2_ans'][1:])

        self.q10 = RadioGroupQ(translation['q10'], translation['q2_ans'])

        self.q11 = RadioGroupQ(translation['q11'], translation['q7_ans'])
        self.q11a = RadioGroupQ(translation['q11a'], translation['q2_ans'])
        self.q11grp = ConditionalWidget(self.q11, self.q11a,
                                        translation['q7_ans'][1])

        self.q12 = RadioGroupQ(translation['q12'], translation['q7_ans'])
        self.q12a = Question12(translation['q12a'], translation['q12a_header'],
                               6)
        self.q12grp = ConditionalWidget(self.q12, self.q12a,
                                        translation['q7_ans'][1])

        layout.addWidget(self.q1)
        layout.addWidget(self.q2grp)
        layout.addWidget(self.q3grp)
        layout.addWidget(self.q4grp)
        layout.addWidget(self.q5grp)
        layout.addWidget(self.q6grp)
        layout.addWidget(self.q7grp)
        layout.addWidget(self.q8grp)
        layout.addWidget(self.q9grp)
        layout.addWidget(self.q10)
        layout.addWidget(self.q11grp)
        layout.addWidget(self.q12grp)
        self.setLayout(layout)