pyqt - 自动更新用户输入的小部件

时间:2015-05-16 00:03:10

标签: python-2.7 pyqt pyqt4

这里总pyqt新手。当用户选择组合框2中的某个选项时,尝试自动修改窗口小部件以显示不同的选项。如果用户选择“Cliff Erosion”,则使用IE浏览器。或者' Dune Erosion',我希望小部件能够使用额外的组合框进行刷新。同样,如果他们选择回到“崛起的潮汐”。或者'沿海洪水'我希望小部件可以回到原始通话状态。如何刷新小部件?

from PyQt4.QtGui import *


# Create window
class Window(QWidget):

    #This block adds features into the window init
    def __init__(self):
        QWidget.__init__(self)
        self.setWindowTitle('Monterey Bay Sea Level Rise')
        self.resize(300, 240)
        self.addWidgets1()


    def addWidgets1(self):


        #Add drop-down list for selecting forecast year
        self.year_lbl = QLabel("1. Select Forecast Year", self)
        self.year_lbl.move(5,0)
        year = QComboBox(self)
        year.addItem('2030')
        year.addItem('2060')
        year.addItem('2100')
        year.move(5,20)

        #Add drop-down list for selecting hazard
        self.hazard_lbl = QLabel("2. Select Coastal Hazard", self)
        self.hazard_lbl.move(5,50)
        hazard = QComboBox(self)
        hazard.addItem('Rising Tides')
        hazard.addItem('Coastal Storm Flooding')
        hazard.addItem('Cliff Erosion')
        hazard.addItem('Dune Erosion')
        hazard.activated[str].connect(self.addWidget2) 
        hazard.move(5,70)

        #Add drop-down list for inputing model intensity (s1,s2,s3)
        self.intensity_lbl = QLabel("3. Select Intensity", self)
        self.intensity_lbl.move(5,100)
        intensity = QComboBox(self)
        intensity.addItem('Low')
        intensity.addItem('Mid')
        intensity.addItem('High') 
        intensity.move(5,120)


    def addWidget2(self,text):
        #if hazard is cliff erosion or dune erosion we want to update the widget
        #... to include wstorm,long_term AND no_change,stormier

        if text == 'Cliff Erosion' or text == 'Dune Erosion':
            print 'Hi'

            self.type_lbl = QLabel("3. Select type of changes", self)
            self.type_lbl.move(5,150)
            types = QComboBox(self)
            types.addItem('Long-term')
            types.addItem('Storm induced')
            types.move(5,180)

            self.storm_lbl = QLabel("4. Select for stormier", self)
            self.storm_lbl.move(5,150)
            storm = QComboBox(self)
            storm.addItem('No Change')
            storm.addItem('Stormier')
            storm.move(5,180)       


if __name__ == '__main__':

    import sys
    app = QApplication(sys.argv)
    window = Window()
    #window.resize(100, 60)
    window.show()

    sys.exit(app.exec_())

1 个答案:

答案 0 :(得分:2)

将小部件添加到Qt应用程序的常规方法是使用layouts。他们将计算您的小部件的首选大小和位置,并在需要时更新,例如添加窗口小部件或调整窗口大小时(注意在执行期间使窗口变小时会发生什么情况并将其与下面的解决方案进行比较)。我确信可以自己完成所有移动和调整大小,但QLayouts确实是要走的路,我强烈建议您也使用它们。

有几种类型的QLayouts但在你的情况下我会使用QFormLayout。令我惊讶的是,QFormLayout确实有addRow方法,但没有相应的removeRow。但是我发现只需在需要时显示/隐藏组合框就可以了。我已经调整了你的例子。

最后,即使只显示或隐藏最后两个组合框也会导致布局略微移动前三个。这是因为第4个标签是其中最长的标签。我发现这很烦人。也许更好的解决方案是在需要时启用/禁用组合框。这具有向用户显示甚至存在这些选项的额外益处。另请参阅下面的代码。第二种方法可能是使用QGridLayout(而不是QFormLayout)并使用setColumnMinimumWidth将第一列设置为包含所有可能标签的大小。

from PyQt4 import QtGui 

# Create window
class Window(QtGui.QWidget):

    #This block adds features into the window init
    def __init__(self):
        QtGui.QWidget.__init__(self)
        self.setWindowTitle('Monterey Bay Sea Level Rise')
        self.resize(300, 240)
        self.addWidgets1()

    def addWidgets1(self):

        self.layout = QtGui.QFormLayout()
        self.setLayout(self.layout)

        #Add drop-down list for selecting forecast year

        # You don't need to set to parent of the widgets to self anymore, the
        # layout will set the parent automatically when you add the widgets
        self.year_lbl = QtGui.QLabel("1. Select Forecast Year")
        # self.year_lbl.move(5,0) # Can be removed. The layout takes care of it.
        year = QtGui.QComboBox()
        year.addItem('2030')
        year.addItem('2060')
        year.addItem('2100')
        self.layout.addRow(self.year_lbl, year)        

        #Add drop-down list for selecting hazard
        self.hazard_lbl = QtGui.QLabel("2. Select Coastal Hazard")
        self.hazard = QtGui.QComboBox()
        self.hazard.addItem('Rising Tides')
        self.hazard.addItem('Coastal Storm Flooding')
        self.hazard.addItem('Cliff Erosion')
        self.hazard.addItem('Dune Erosion')
        self.hazard.activated[str].connect(self.updateComboboxes) 
        self.layout.addRow(self.hazard_lbl, self.hazard)        

        #Add drop-down list for inputing model intensity (s1,s2,s3)
        self.intensity_lbl = QtGui.QLabel("3. Select Intensity")
        intensity = QtGui.QComboBox()
        intensity.addItem('Low')
        intensity.addItem('Mid')
        intensity.addItem('High') 
        self.layout.addRow(self.intensity_lbl, intensity)        

        self.types_lbl = QtGui.QLabel("3. Select type of changes")
        self.types = QtGui.QComboBox()
        self.types.addItem('Long-term')
        self.types.addItem('Storm induced')
        self.layout.addRow(self.types_lbl, self.types)        

        self.storm_lbl = QtGui.QLabel("4. Select for stormier")
        self.storm = QtGui.QComboBox()
        self.storm.addItem('No Change')
        self.storm.addItem('Stormier')
        self.layout.addRow(self.storm_lbl, self.storm)        

        # show initial state
        self.updateComboboxes() 


    def updateComboboxes(self, text=None):
        #if hazard is cliff erosion or dune erosion we want to update the widget
        #... to include wstorm,long_term AND no_change,stormier

        if text is None:
            text = self.hazard.currentText()

        usable = (text == 'Cliff Erosion' or text == 'Dune Erosion')

        if True: # change to False to use enabling/disabling widgets
            # May cause other widgets to be relocated
            self.types_lbl.setVisible(usable)
            self.types.setVisible(usable)
            self.storm_lbl.setVisible(usable)
            self.storm.setVisible(usable)
        else:
            # This option doesn't relocate widgets
            # Also may give additional clue to the uses that this exsits
            self.types_lbl.setEnabled(usable)
            self.types.setEnabled(usable)
            self.storm_lbl.setEnabled(usable)
            self.storm.setEnabled(usable)

if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    window = Window()
    #window.resize(100, 60)
    window.show()
    sys.exit(app.exec_())