Jeremy Westfall
Jeremy Westfall

Reputation: 21

How to get the cell position of QCombobox which is a QTableWidgetItem

So the below code is part of a bigger project but in general, I have a QTableWidget which is populated from a database. One of the items is a combobox which when the user selects a milestone option from the combobox I want to be able to know which row and column the combo box that was select is in so I can then apply a fixed rate to the value of a cell in the same row. All I need help on is how to track which cell (row, column) the combo box that was selected is in.

Please note im using other tabs that are not shown and is why my code is setup the way it is. I found some other help but am not a very experience python programmer so I got stuck.

#!/usr/local/bin/python
# -*- coding: latin9 -*-
import sys, os , random
from PyQt4 import QtGui, QtCore
from PyQt4.QtCore import pyqtSlot,SIGNAL,SLOT
import time
import json
import openpyxl
import Lists

class CashflowTab(QtGui.QDialog):
    '''
    Parent for all tab widgets of the REPO GUI
    '''
    def __init__(self, parent = None):
        super(CashflowTab, self).__init__()
        if parent != None:
            self.setParent(parent)
        self.initUI()
        self.loadSettings()

    def loadSettings(self):
        '''
        read settings and read db
        '''
        fh = open('settings.json')
        self.settings = json.load(fh)
        fh.close()
        #load db
        dbpath = self.settings['dbpath']
        self.db = Lists.SQLiteHandler(dbpath)
        self.repo = Lists.WCNList('ROSQL')

        try:
            self.db.read(self.repo)
        except:
            pass

class WCNSelectTab(CashflowTab):
    '''
    Window for WCN selection
    '''
    def __init__(self, parent = None):
        super(WCNSelectTab, self).__init__(parent)
        if parent != None:
            self.setParent(parent)


    def initUI(self):
        global wbsitem, WCNSelectTab_object, linequerycheck
        linequerycheck = 'False'
        wbsitem = 'null'
        QtGui.QApplication.setStyle(QtGui.QStyleFactory.create("cleanlooks"))
        gbox = QtGui.QGridLayout(self)

        self.projectlist = QtGui.QTableWidget()
        self.projectlist.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
        #self.projectlist.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
        self.projectlist.setColumnCount(3)
        self.projectlist.setHorizontalHeaderLabels(QtCore.QStringList(['WBS','Service','Milestone']))
        self.projectlist.setColumnWidth(0, 100)       
        self.projectlist.setColumnWidth(1, 100)
        self.projectlist.setColumnWidth(2, 150)

        gbox.addWidget(self.projectlist,5,0,3,6)

        self.getAwardBudget()

    def getAwardBudget(self):

        global wbs_details

        wbs_details = []
        wbs_details.append(["123", "Service 1"])
        wbs_details.append(["456", "Service 2"])        
        print wbs_details

        self.projectlist.setRowCount(len(wbs_details))
        for n,item in enumerate(wbs_details):            

            qitem = QtGui.QTableWidgetItem(item[0])
            self.projectlist.setItem(n, 0, qitem)
            qitem = QtGui.QTableWidgetItem(item[1])
            self.projectlist.setItem(n, 1, qitem)
            milestone_options = ["Award","Mobilization","Survey"]
            milestonecombo = QtGui.QComboBox()
            for t in milestone_options:
                milestonecombo.addItem(t)
            milestonecombo.setFixedWidth(150)
            self.projectlist.setCellWidget(n, 2, milestonecombo)


class RepoGUI(QtGui.QMainWindow):
    '''
    Main Widget for REPO helper
    '''
    def __init__(self):
        super(RepoGUI, self).__init__()
        #self.mode = mode
        self.initUI()

    def initUI(self):
        global approval, approval_names, username, approval_names
        self.tabs = QtGui.QTabWidget()
        self.setCentralWidget(self.tabs)
        self.tabs.setAutoFillBackground(1)

        fh = open('settings.json')
        settings = json.load(fh)
        fh.close()

        if settings['WCNsubmit'] == 1:
            self.tabs.addTab(WCNSelectTab(), 'WCN Creation') 

        self.setWindowTitle('Work Completion Notification')  
        self.setGeometry(300, 150, 1400, 800)
        self.setStyleSheet('font-size: %ipt' %settings['fontsize'])   

        self.show()    

def main(): 
    app = QtGui.QApplication(sys.argv)
    ex = RepoGUI()

    sys.exit(app.exec_())

if __name__ == '__main__':

    main()

Upvotes: 1

Views: 777

Answers (1)

eyllanesc
eyllanesc

Reputation: 243887

A possible solution is to use indexAt() since the position of the QComboBox is relative to the viewport(), but to obtain the QComboBox that was selected we use sender().

    for n,item in enumerate(wbs_details):            

        qitem = QtGui.QTableWidgetItem(item[0])
        self.projectlist.setItem(n, 0, qitem)
        qitem = QtGui.QTableWidgetItem(item[1])
        self.projectlist.setItem(n, 1, qitem)
        milestone_options = ["Award","Mobilization","Survey"]
        milestonecombo = QtGui.QComboBox()
        milestonecombo.addItems(milestone_options)
        milestonecombo.setFixedWidth(150)
        milestonecombo.currentIndexChanged[str].connect(self.onCurrentIndexChanged)
        self.projectlist.setCellWidget(n, 2, milestonecombo)

def onCurrentIndexChanged(self, text):
    combobox = self.sender()
    ix = self.projectlist.indexAt(combobox.pos())
    print(ix.row(), ix.column(), text)

Another possible solution is to use the property:

    for n,item in enumerate(wbs_details):            

        qitem = QtGui.QTableWidgetItem(item[0])
        self.projectlist.setItem(n, 0, qitem)
        qitem = QtGui.QTableWidgetItem(item[1])
        self.projectlist.setItem(n, 1, qitem)
        milestone_options = ["Award","Mobilization","Survey"]
        milestonecombo = QtGui.QComboBox()
        milestonecombo.addItems(milestone_options)
        milestonecombo.setFixedWidth(150)
        milestonecombo.setProperty("row", n)
        milestonecombo.setProperty("column", 1)
        milestonecombo.currentIndexChanged[str].connect(self.onCurrentIndexChanged)
        self.projectlist.setCellWidget(n, 2, milestonecombo)

def onCurrentIndexChanged(self, text):
    combobox = self.sender()
    r = combobox.property("row").toPyObject()
    c = combobox.property("column").toPyObject()
    print(r, c, text)

Upvotes: 1

Related Questions