简体   繁体   English

如何修改QGroupBox的QLayout以删除或添加参数QTextEdit输入? (Python,PyQt)

[英]How do I modify a QLayout of a QGroupBox to remove or add parameter QTextEdit input? (Python, PyQt)

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). 在此窗口中,用户应给出多行(具有N个参数集)。 From this number I would like to have the automatically generation of QTextEdit sets for each N parameter set. 从这个数字,我想为每个N参数集自动生成QTextEdit集。 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. 因此,我想单击的是“运行”(右上角的数字为N行),然后修改窗口下部的参数集数量。 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): 我开始进行窗口更新,但是我一直在努力寻找正确的代码以放入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. 嗨,@ jgorosdev,谢谢您的回答。 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. 在您给我的代码中,它可以正常工作,因为参数集始终在窗口底部更新,但是在我更高级的软件中,后面还有一些其他QGroupBox。 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. 您在代码中两次创建了底部的groupbox,我认为这是一种更好的方法。 I have packed everything in the UpdateLayout function. 我已经将所有内容打包在UpdateLayout函数中。

You'll probably need to re-check the resizing qt policy to properly resize the main window. 您可能需要重新检查大小调整qt策略,以正确调整主窗口的大小。

The code with UPDATE : 带有UPDATE的代码:

 # -*- 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)
        # NEW
        self.mainHBOX_param_scene.insertWidget(1,self.horizontalGroupBox_Param2)

        return

if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = SurfViewer(app)
    ex.show()
    sys.exit(app.exec_())

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 the insertWidget() function. 如果您愿意在不更改位置的情况下更新 QGroupBox,则您需要的功能不是addWidget() ,而是insertWidget()函数。

I have updated the line in the UpdateLayout function that was adding the widget. 我已经更新了添加小部件的UpdateLayout函数中的行。 Hope that suits fine for you. 希望适合您。

The reference of the function is next: 接下来是该函数的参考:

http://doc.qt.io/qt-4.8/qboxlayout.html#insertWidget http://doc.qt.io/qt-4.8/qboxlayout.html#insertWidget

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM