I'm trying to implement a window that is able to get parameters from a user. In this window, the user should give a number of lines (to have N parameter sets). From this number I would like to have the automatically generation of QTextEdit
sets for each N
parameter set. So from now I have this code
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from PyQt4 import QtGui
import sys
import numpy as np
class SurfViewer(QtGui.QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
# General Window
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QtGui.QVBoxLayout()
# parameter2
self.horizontalGroupBox_Param2 = QtGui.QGroupBox("Set range Parameter 2 for matrix method")
self.horizontalGroupBox_Param2.setMaximumHeight(80)
self.Param2_layout = QtGui.QVBoxLayout()
grid2 = QtGui.QGridLayout()
self.Param2_layout.addLayout(grid2)
self.Param2_Label = QtGui.QLabel('Name')
self.Param2 = QtGui.QComboBox()
self.Param2.addItems(["a","b","c"])
self.Param2.setMinimumWidth(100)
# self.Param2_layout.addWidget(self.Param2)
self.Param2_min_Label = QtGui.QLabel('min')
self.Param2_min_Edit = QtGui.QTextEdit('1')
self.Param2_min_Edit.setMaximumWidth(40)
self.Param2_max_Label = QtGui.QLabel('max')
self.Param2_max_Edit = QtGui.QTextEdit('5')
self.Param2_max_Edit.setMaximumWidth(40)
self.Param2_step_Label = QtGui.QLabel('step')
self.Param2_step_Edit = QtGui.QTextEdit('1')
self.Param2_step_Edit.setMaximumWidth(40)
grid2.addWidget(self.Param2_Label, 0, 0)
grid2.addWidget(self.Param2, 1, 0)
grid2.addWidget(self.Param2_min_Label, 0, 1)
grid2.addWidget(self.Param2_min_Edit, 1, 1)
grid2.addWidget(self.Param2_max_Label, 0, 2)
grid2.addWidget(self.Param2_max_Edit, 1, 2)
grid2.addWidget(self.Param2_step_Label, 0, 3)
grid2.addWidget(self.Param2_step_Edit, 1, 3)
self.horizontalGroupBox_Param2.setLayout(self.Param2_layout)
#action button
self.horizontalGroupBox_Actions = QtGui.QGroupBox("Actions")
self.horizontalGroupBox_Actions.setMaximumHeight(100)
self.layout_Actions = QtGui.QHBoxLayout()
self.Button_Run=QtGui.QPushButton('Run')
self.nbparam = QtGui.QTextEdit('2')
self.nbparam.setMaximumHeight(30)
self.nbparam.setMaximumWidth(50)
self.layout_Actions.addWidget(self.Button_Run)
self.layout_Actions.addWidget(self.nbparam)
self.horizontalGroupBox_Actions.setLayout(self.layout_Actions)
# set layout
self.mainHBOX_param_scene.addWidget(self.horizontalGroupBox_Actions)
self.mainHBOX_param_scene.addWidget(self.horizontalGroupBox_Param2)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
self.Button_Run.clicked.connect(self.Runclick)
def Runclick(self):
# parameter2
self.horizontalGroupBox_Param = QtGui.QGroupBox("Set range Parameter 2 for matrix method")
nbparam = int(self.nbparam.toPlainText())
self.Param_layout = QtGui.QVBoxLayout()
grid2 = QtGui.QGridLayout()
self.Param_layout.addLayout(grid2)
self.Param_Label = QtGui.QLabel('Names')
self.Param_min_Label = QtGui.QLabel('mins')
self.Param_max_Label = QtGui.QLabel('maxs')
self.Param_step_Label = QtGui.QLabel('steps')
grid2.addWidget(self.Param_Label, 0, 0)
grid2.addWidget(self.Param_min_Label, 0, 1)
grid2.addWidget(self.Param_max_Label, 0, 2)
grid2.addWidget(self.Param_step_Label, 0, 3)
self.listofedit = []
text=["a","b","c"]
for i in np.arange(nbparam):
print(i)
self.listofedit.append([QtGui.QComboBox(),QtGui.QTextEdit('10'),QtGui.QTextEdit('50'),QtGui.QTextEdit('10')])
self.listofedit[i][0].addItems(text)
self.listofedit[i][0].setMinimumWidth(100)
self.listofedit[i][1].setMaximumWidth(40)
self.listofedit[i][2].setMaximumWidth(40)
self.listofedit[i][3].setMaximumWidth(40)
grid2.addWidget(self.listofedit[i][0], i+1, 0)
grid2.addWidget(self.listofedit[i][1], i+1, 1)
grid2.addWidget(self.listofedit[i][2], i+1, 2)
grid2.addWidget(self.listofedit[i][3], i+1, 3)
self.horizontalGroupBox_Param.setLayout(self.Param_layout)
# while self.horizontalGroupBox_Param2.layout().count():
# self.horizontalGroupBox_Param2.layout().itemAt(0).widget().deleteLater()
self.horizontalGroupBox_Param2.layout().clear()
self.horizontalGroupBox_Param2.setLayout(self.Param_layout)
return
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = SurfViewer(app)
ex.show()
sys.exit(app.exec_())
Which generate me this window :
So What I would like is when I click on Run (the number to the top right corner is the number of lines N), I modify the number of parameter sets in the lower part of the window. So in this case I should have two lines to enter two names, two min, two max and two step values. I started to do the update of the window but I'm struggling to find the correct code to put in def Runclick(self):
I already write the code to generate the correct number of parameter set lines but I cannot manage to update my window with them.
I clearly doing something wrote with the final part :
self.horizontalGroupBox_Param.setLayout(self.Param_layout)
# while self.horizontalGroupBox_Param2.layout().count():
# self.horizontalGroupBox_Param2.layout().itemAt(0).widget().deleteLater()
self.horizontalGroupBox_Param2.setLayout(self.Param_layout)
I think I'm not taking things in the correct way. So If somebody have a solution to that, I will be grateful
UPDATE
Hi @jgorosdev, thanks for your answer. Although, it not corresponding exactly to what I would like. In the code you gave me, it work correctly because the parameter sets are always update at the bottom of the window but in my more advance soft, there are some others QGroupBox after. For instance if I add a console like part:
# -*- coding: utf-8 -*-
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
from __future__ import unicode_literals
from PyQt4 import QtGui
import sys
import numpy as np
class SurfViewer(QtGui.QMainWindow):
def __init__(self, parent=None):
super(SurfViewer, self).__init__()
# General Window
self.centralWidget = QtGui.QWidget()
self.setCentralWidget(self.centralWidget)
self.mainHBOX_param_scene = QtGui.QVBoxLayout()
#action button
self.horizontalGroupBox_Actions = QtGui.QGroupBox("Actions")
self.horizontalGroupBox_Actions.setMaximumHeight(100)
self.layout_Actions = QtGui.QHBoxLayout()
self.Button_Run=QtGui.QPushButton('Run')
self.nbparam = QtGui.QTextEdit('3')
self.nbparam.setMaximumHeight(30)
self.nbparam.setMaximumWidth(50)
self.layout_Actions.addWidget(self.Button_Run)
self.layout_Actions.addWidget(self.nbparam)
self.horizontalGroupBox_Actions.setLayout(self.layout_Actions)
self.mainHBOX_param_scene.addWidget(self.horizontalGroupBox_Actions)
self.centralWidget.setLayout(self.mainHBOX_param_scene)
self.updateWidget = None
# Param2 layout
self.horizontalGroupBox_Param2 = QtGui.QGroupBox("Set range Parameter 2 for matrix method")
self.Param2_layout = QtGui.QVBoxLayout()
self.Button_Run.clicked.connect(self.UpdateLayout)
self.UpdateLayout()
# console
self.horizontalGroupBox_Console2 = QtGui.QGroupBox("Console ")
self.layout_Consol_Label2 = QtGui.QVBoxLayout()
self.Consol_Label2 = QtGui.QTextEdit('Console :')
self.layout_Consol_Label2.addWidget(self.Consol_Label2)
self.horizontalGroupBox_Console2.setLayout(self.layout_Consol_Label2)
self.mainHBOX_param_scene.addWidget(self.horizontalGroupBox_Console2)
# parameter2
# From now on everything well be created inside a function that updates the layout
def UpdateLayout(self):
if (self.updateWidget == None):
self.updateWidget = QtGui.QWidget()
else:
self.mainHBOX_param_scene.removeWidget(self.updateWidget)
self.updateWidget.deleteLater()
self.updateWidget = None
cnt = self.mainHBOX_param_scene.layout().count()
print("Widget count:" +str(cnt)+ "")
nbparam = int(self.nbparam.toPlainText())
#self.horizontalGroupBox_Param2.setMaximumHeight(150)
grid2 = QtGui.QGridLayout()
self.Param2_Label = QtGui.QLabel('Name')
self.Param2 = QtGui.QComboBox()
self.Param2.addItems(["a","b","c"])
self.Param2.setMinimumWidth(100)
# self.Param2_layout.addWidget(self.Param2)
self.Param2_min_Label = QtGui.QLabel('min')
self.Param2_max_Label = QtGui.QLabel('max')
self.Param2_step_Label = QtGui.QLabel('step')
grid2.addWidget(self.Param2_Label, 0, 0)
grid2.addWidget(self.Param2_min_Label, 0, 1)
grid2.addWidget(self.Param2_max_Label, 0, 2)
grid2.addWidget(self.Param2_step_Label, 0, 3)
self.listofedit = []
text=["a","b","c"]
for i in np.arange(nbparam):
print(i)
self.listofedit.append([QtGui.QComboBox(),QtGui.QTextEdit('20'),QtGui.QTextEdit('50'),QtGui.QTextEdit('10')])
self.listofedit[i][0].addItems(text)
self.listofedit[i][0].setMinimumWidth(100)
self.listofedit[i][1].setMaximumWidth(40)
self.listofedit[i][1].setMaximumHeight(40)
self.listofedit[i][2].setMaximumWidth(40)
self.listofedit[i][2].setMaximumHeight(40)
self.listofedit[i][3].setMaximumWidth(40)
self.listofedit[i][3].setMaximumHeight(40)
grid2.addWidget(self.listofedit[i][0], i+1, 0)
grid2.addWidget(self.listofedit[i][1], i+1, 1)
grid2.addWidget(self.listofedit[i][2], i+1, 2)
grid2.addWidget(self.listofedit[i][3], i+1, 3)
self.updateWidget = QtGui.QWidget()
self.updateWidget.setLayout(grid2)
#self.updateWidget.setMaximumHeight(nbparam*60)
self.Param2_layout.addWidget(self.updateWidget)
self.horizontalGroupBox_Param2.setLayout(self.Param2_layout)
self.mainHBOX_param_scene.addWidget(self.horizontalGroupBox_Param2)
return
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
ex = SurfViewer(app)
ex.show()
sys.exit(app.exec_())
I have this window at the beginning :
Which is what I would like but i get this image after clicking on the Run button :
So the console and the parameter set are inverted. I'm wondering if it is possible to replace a part of the layout without build all the layout again?
I have made some minor changes in the code and now works well.
You were creating the bottom groupbox two times in your code, and I think that this is a better way. I have packed everything in the
UpdateLayout
function.You'll probably need to re-check the resizing qt policy to properly resize the main window.
The code with UPDATE:
Answer to UPDATE
If you are willing to have the updating QGroupBox without chaning the position, instead of
addWidget()
the function you are going to need is theinsertWidget()
function.I have updated the line in the
UpdateLayout
function that was adding the widget. Hope that suits fine for you.The reference of the function is next:
http://doc.qt.io/qt-4.8/qboxlayout.html#insertWidget