How can I get the index of the row of a QComboBox that I have inserted in a cell of a QTableWidget?



  • I have a QTableWidget in which the first column contains a number of QComboBox with two possible values ("Hold" and "Heat up"). In the method showTemperature() i create as many QComboBox as the number of the record i want to show in the QTableWidget. I also connect these QComboBox to the method "actionQcbTemperatureStep_itemChanged(), that should update the corresponding record in the model if the value of the QComboBox changes. Where I put ??? i need the index of the row in which the QComboBox that has just changed its value is positioned in the QTableWidget. For example, if I set the value of the QComboBox at the second row of the QTableWidget to "Heat up", then i want to update the second record in my model.

    in order to get this information, I already tried to exploit the event "clicked" of the QTableWidget, in order to put the value of the current row in a global variable. Unfortunately, this event is called only when I click on a cell that doesn't contain another widget like a QComboBox. Here you can see a portion of my code (twTemperatureCurve is the QTableWidget i'm filling):

    
        private void showTemperatureCurve()  {
            /*
           here I fill the QTableWidget
           */
            for (int i = 0; i < temperatureCurve.size(); i++) {
                qcbTemperatureStep = new QComboBox();
                String currentTemperatureStepType = temperatureCurve.get(i).getStepType();
                qcbTemperatureStep.addItem(currentTemperatureStepType);
                if (currentTemperatureStepType.equals("Heat up")) {
                    qcbTemperatureStep.addItem("Hold");
                } else {
                    qcbTemperatureStep.addItem("Heat up");
                }
                ui.twTemperatureCurve.setCellWidget(i, 0, qcbTemperatureStep);
                qcbTemperatureStep.currentIndexChanged.connect(this, "actionQcbTemperatureStep_itemChanged()");
            }
            ui.twTemperatureCurve.resizeColumnsToContents();
        }
    
        QComboBox qcbTemperatureStep;
        int twTemperatureCurveCurrentRow = 0;
    
        private void actionQcbTemperatureStep_itemChanged() {        
            TemperatureStep temperatureStep = MainWindowModel.getOven().getTemperatureCurve().get(???);
            if (temperatureStep.getStepType().equals("Hold")) {
                temperatureStep.setStepType("Heat up");
            } else {
                temperatureStep.setStepType("Hold");
            }  
            showTemperatureCurve();
            temperatureCurveModified = true;
        }
    

    Thanks in advance for any help


  • Lifetime Qt Champion

    Hi,

    Rather than generating that much widgets, why not create a QStyledItemDelegate for that column ? Then you only have to parse the model to get the data you want.



  • Thanks, I haven't found an example of how to use QStyledItemDelegate in QtJambi (if somebody of you have one I would like to see it) but i arranged another solution.

    [I've found here a way to pass additional arguments to a methods that you want to connect to an event for Python and C++:

    http://eli.thegreenplace.net/2011/07/09/passing-extra-arguments-to-qt-slots
    http://eli.thegreenplace.net/2011/04/25/passing-extra-arguments-to-pyqt-slot

    but I haven't found a similar thing for Java and QtJambi (if somobody of you have one i would like to see it)]

    So, this is what I've done:

    public class QComboBoxExtended extends QComboBox {
    
        int index;
    
        public void setIndex(int index) {
            this.index = index;
        }
    
        public int getIndex(int index) {
            return index;
        }
    
        @Override
        protected void mousePressEvent(QMouseEvent e) {
            MainWindowController.qcbTemperatureStepClickedIndex = index;
            super.mousePressEvent(e); 
        }
    }
    

    When I create the QComboBoxExtended, I set index with 'i' (a value that identifies a temperatureStep in my model). Then, when I click on the QComboBoxExtended, it says to the controller his index. So, when the method actionQcbTemperatureStep_itemChanged() is called, the correct temperatureStep will be modified by using the index sent by the QComboBoxExtended.


  • Lifetime Qt Champion

    Most likely you have to subclass it the same way you would in C++ but adapted to Java.

    Your current implementation looks suspicious. What dose MainWindowController do in that combo box ?



  • Here is my code. I fill my QTableWidget by taking all the values of the attributes of each element of my model (a temperatureStep). The first column should assume the values "Hold" or "Heat up", this is the reason why I use a QComboBox (extendend, in order to recognise which temperatureStep I have to modify when the value of the QComboBox changes).

     private void showTemperatureCurve() {
            List<TemperatureStep> temperatureCurve = MainWindowModel.getOven().getTemperatureCurve();
            ui.twTemperatureCurve.blockSignals(true);
            int j = 0;
            ui.twTemperatureCurve.setRowCount(0);
            for (TemperatureStep temperatureStep : temperatureCurve) {
                ui.twTemperatureCurve.setRowCount(ui.twTemperatureCurve.rowCount() + 1);
                List<String> attributes = new ArrayList<>();
                List<Object> values = new ArrayList<>();
    
                for (PropertyDescriptor propertyDescriptor
                        : Introspector.getBeanInfo(temperatureStep.getClass(), Object.class).getPropertyDescriptors()) {
                    attributes.add(propertyDescriptor.getDisplayName());
                    //System.out.println(propertyDescriptor.getReadMethod());
                }
                for (String attribute : attributes) {
                    Object value = BeanUtils.getProperty(temperatureStep, attribute);
                    values.add(value);
                    //System.out.println(attribute + " " + value.toString());
                }
    
                List<String> headerLabelsTemperatureCurveNU = Arrays.asList("stepType", "endTemperature", "maxSlope", "minTime");
    
                for (int i = 0; i < attributes.size(); i++) {
                    ui.twTemperatureCurve.setItem(j, headerLabelsTemperatureCurveNU.indexOf(attributes.get(i)), new QTableWidgetItem(values.get(i).toString()));
                }
                j += 1;
            }
            ui.twTemperatureCurve.blockSignals(false);
    
            for (int i = 0; i < temperatureCurve.size(); i++) {
                QComboBoxExtended qcbTemperatureStep = new QComboBoxExtended();
                qcbTemperatureStep.setIndex(i);
                String currentTemperatureStepType = temperatureCurve.get(i).getStepType();
                qcbTemperatureStep.addItem(currentTemperatureStepType);
                if (currentTemperatureStepType.equals("Heat up")) {
                    qcbTemperatureStep.addItem("Hold");
                } else {
                    qcbTemperatureStep.addItem("Heat up");
                }
                ui.twTemperatureCurve.setCellWidget(i, 0, qcbTemperatureStep);
                qcbTemperatureStep.currentIndexChanged.connect(this, "actionQcbTemperatureStep_itemChanged()");
            }
            ui.twTemperatureCurve.resizeColumnsToContents();
        }
    
        public static int qcbTemperatureStepClickedIndex;
    
        private void actionQcbTemperatureStep_itemChanged()  {
            TemperatureStep temperatureStep = MainWindowModel.getOven().getTemperatureCurve().get(qcbTemperatureStepClickedIndex);
            if (temperatureStep.getStepType().equals("Hold")) {
                temperatureStep.setStepType("Heat up");
            } else {
                temperatureStep.setStepType("Hold");
            }
            showTemperatureCurve();
        }
    

Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.