Search code examples
pythonpyqtpyqt4qgis

Is there a PyQt table/ listview that can be filled dynamically with comboboxes in one of the columns?


I'm using PyQt for a qgis plugin. I'd like to have some sort of table/ listview with the first column being layers from the open shapefile, then the second column being comboboxes that will be loaded with values from a database input. Is this possible and if so do I need to use listview, tableview, or treeview? Thanks in advance!!


Solution

  • If I correct understood you, I've done something quite similar a while ago.

    In my case I wanted to populate the following QTableWidget with QDoubleSpinBoxes and set specific properties for each of them.

    enter image description here

    So I made a "model" empty QTableWidget in QDesigner and in my code I used the following function:

    Populate QTableWidget

    def QTableWidget_populate(self, table):
        # Create an empty matrix with the same dimensions as your table
        self.ele_mat = [
            [0 for x in range(table.columnCount())] for x in range(table.rowCount())]
        # For each cell in the table define its characteristics
        for row in xrange(table.rowCount()):
            for column in xrange(table.columnCount()):
                # Define row name prefix
                if row == 0:
                    element = 'Begin_'
                elif row == 1:
                    element = 'MidMinus_'
                elif row == 2:
                    element = 'MidPlus_'
                elif row == 3:
                    element = 'End_'
    
                # Define columns paraters
                if column == 0:
                    element += 'Pow'    # Name column sufix
                    param1 = '2'        # setDecimals settings
                    param2 = '-99,99'   # setRange
                    param3 = '"dBm"'    # seSuffix
                elif column == 1:
                    element += 'PD'
                    param1 = '0'
                    param2 = '0,999'
                    param3 = '"uA"'
                elif column == 2:
                    element += 'TMVoltage'
                    param1 = '2'
                    param2 = '-99,99'
                    param3 = '"V"'
                elif column == 3:
                    element += 'Wav'
                    param1 = '1'
                    param2 = '0,2000'
                    param3 = '"nm"'
                # Popule matrix with dict of parameters
                self.ele_mat[row][column] = {
                    'name': element, 'type': 'QtGui.QDoubleSpinBox()',
                                             'Adjustments': ['setDecimals', 'setRange', 'setSuffix'],
                                             'Params':  [param1, param2, param3]}
        # Using the matrix populate the QTableWidget                                  
        for row in xrange(table.rowCount()):
            for column in xrange(table.columnCount()):
                # Create Widget with name and type defined in the matrix
                exec('self.{} = {}' .format(
                    self.ele_mat[row][column]['name'],
                    self.ele_mat[row][column]['type']))
    
                # Give it its settings
                for adjustment, param in zip(self.ele_mat[row][column]['Adjustments'],
                                             self.ele_mat[row][column]['Params']):
                    exec('self.{}.{}({})' .format(self.ele_mat[
                         row][column]['name'], adjustment, param))
    
                # Set the created widget to the QTableWidget
                table.setCellWidget(row, column, eval(
                    'self.{}' .format(self.ele_mat[row][column]['name'])))
    
        # For better clarity in GUI
        table.horizontalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
        table.verticalHeader().setResizeMode(QtGui.QHeaderView.Stretch)
    

    I don't know exactly how is the format from the file you are reading but I'm sure you can add a for loop inside my function to setValue to the QDoubleSpinBox according to entries in your file. Furthermore, you can set the Header Labels via code as well using the setVerticalHeaderLabels and setHorizontalHeaderLabelsmethods.

    Even though I use pyqt, I generally use pyside's documentation because they are most of the times equal and pyside's is much easier to read and navigate through. QTableWidget Docs

    Hope it was helpful.