How to dynamically populate a Qt Window with labels and text input fields
-
wrote on 5 Mar 2022, 19:02 last edited by bbsrn 3 Jul 2022, 16:46
I am creating a basic testing tool for an API, with the following primitive design:
Whenever the combo box is changed, the fields "Test Input" and "Expected Output" should be populated with the labels and input text fields of the related data call. Each data call has different input and output parameters, therefore I cannot create static input fields. I have a mapping for each data call and related input-output parameters. How can I use this mapping to dynamically create labels and text input fields on the UI?
Any help is appreciated, thanks!
Edit: I could manage how to dynamically populate the UI based on my mapping. It works now for the initial setting of the combo box, but when I change the combo box, UI is not affected. I think I should clear the QScrollArea on each change, but I couldn't manage how to do so.
self.input_scrollArea = QtWidgets.QScrollArea(self.centralwidget) self.input_scrollArea.setWidgetResizable(True) self.input_scrollArea.setGeometry(QtCore.QRect(50, 90, 311, 311)) self.input_scrollArea.setObjectName("input_scrollArea") self.input_scrollAreaWidgetContents = QtWidgets.QWidget() self.input_scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 309, 309)) self.input_scrollAreaWidgetContents.setObjectName("input_scrollAreaWidgetContents") self.input_scrollArea.setWidget(self.input_scrollAreaWidgetContents) def on_combobox_data_call_changed(self, combobox_index): data_call_name = list(DATA_CALL_MAP.keys())[combobox_index] y_pos = 40 for param in DATA_CALL_MAP[data_call_name]["required_params"]: exec(f"self.label_{param} = QtWidgets.QLabel(self.input_scrollAreaWidgetContents)") exec(f"self.label_{param}.setGeometry(QtCore.QRect(10, {y_pos}, 125, 21))") exec(f"self.label_{param}.setObjectName(\"label_{param}\")") exec(f"self.label_{param}.setText(_translate(\"TestCaseWindow\", \"{param}:\"))") exec(f"self.input_{param} = QtWidgets.QLineEdit(self.input_scrollAreaWidgetContents)") exec(f"self.input_{param}.setGeometry(QtCore.QRect(150, {y_pos}, 125, 21))") exec(f"self.input_{param}.setObjectName(\"input_{param}\")") y_pos += 40
-
I am creating a basic testing tool for an API, with the following primitive design:
Whenever the combo box is changed, the fields "Test Input" and "Expected Output" should be populated with the labels and input text fields of the related data call. Each data call has different input and output parameters, therefore I cannot create static input fields. I have a mapping for each data call and related input-output parameters. How can I use this mapping to dynamically create labels and text input fields on the UI?
Any help is appreciated, thanks!
Edit: I could manage how to dynamically populate the UI based on my mapping. It works now for the initial setting of the combo box, but when I change the combo box, UI is not affected. I think I should clear the QScrollArea on each change, but I couldn't manage how to do so.
self.input_scrollArea = QtWidgets.QScrollArea(self.centralwidget) self.input_scrollArea.setWidgetResizable(True) self.input_scrollArea.setGeometry(QtCore.QRect(50, 90, 311, 311)) self.input_scrollArea.setObjectName("input_scrollArea") self.input_scrollAreaWidgetContents = QtWidgets.QWidget() self.input_scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 309, 309)) self.input_scrollAreaWidgetContents.setObjectName("input_scrollAreaWidgetContents") self.input_scrollArea.setWidget(self.input_scrollAreaWidgetContents) def on_combobox_data_call_changed(self, combobox_index): data_call_name = list(DATA_CALL_MAP.keys())[combobox_index] y_pos = 40 for param in DATA_CALL_MAP[data_call_name]["required_params"]: exec(f"self.label_{param} = QtWidgets.QLabel(self.input_scrollAreaWidgetContents)") exec(f"self.label_{param}.setGeometry(QtCore.QRect(10, {y_pos}, 125, 21))") exec(f"self.label_{param}.setObjectName(\"label_{param}\")") exec(f"self.label_{param}.setText(_translate(\"TestCaseWindow\", \"{param}:\"))") exec(f"self.input_{param} = QtWidgets.QLineEdit(self.input_scrollAreaWidgetContents)") exec(f"self.input_{param}.setGeometry(QtCore.QRect(150, {y_pos}, 125, 21))") exec(f"self.input_{param}.setObjectName(\"input_{param}\")") y_pos += 40
-
@bbsrn
Have you seen Qt'sQDataWidgetMapper
?
Otherwise just change you labels' texts in response to combo value change.wrote on 5 Mar 2022, 22:18 last edited by@JonB Thanks for the answer! I haven't seen this class, because I was trying to create the UI using the designer. Changing labels' texts in response to combo value is okay, but each data call has a different number of parameters, so each combo box change should show a different number of labels and input text boxes. This is twisting my arm, actually.
-
@JonB Thanks for the answer! I haven't seen this class, because I was trying to create the UI using the designer. Changing labels' texts in response to combo value is okay, but each data call has a different number of parameters, so each combo box change should show a different number of labels and input text boxes. This is twisting my arm, actually.
wrote on 5 Mar 2022, 22:32 last edited by JonB 3 May 2022, 22:33@bbsrn
So if that's what's required that's what you'll have to code. You can create/destroy/hide/show/change text for whatever number of widgets happen to be needed for each case.Don't get too hung up in the designer, you can create/populate/show widgets dynamically in code.
You might also consider a
QStackedWidget
for each "page" --- holding all widgets/labels for a given combo value. In that case you can design each page in the designer. But you will have separate widgets to be addressed on every page instead of any "shared" ones across every page. Pros & cons. -
@bbsrn
So if that's what's required that's what you'll have to code. You can create/destroy/hide/show/change text for whatever number of widgets happen to be needed for each case.Don't get too hung up in the designer, you can create/populate/show widgets dynamically in code.
You might also consider a
QStackedWidget
for each "page" --- holding all widgets/labels for a given combo value. In that case you can design each page in the designer. But you will have separate widgets to be addressed on every page instead of any "shared" ones across every page. Pros & cons.wrote on 7 Mar 2022, 16:48 last edited byThis post is deleted!
1/5