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)
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])
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])
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)
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)
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)
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?')
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)
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)
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)
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)
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)
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)
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))
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)
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)
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)