1

I have a scenario where I have a table and I want to display a list widget under a particular cell which I click.i am getting the click on cell in the first column and want to use on click on only first cell.(cell click is implemented here) . the only problem is how to display list under cell now.?!?!?!

Initial View

enter image description here

Final

enter image description here My Code for Table is :-

from untitled import *
from PyQt4 import QtGui # Import the PyQt4 module we'll need
import sys # We need sys so that we can pass argv to QApplication
import os

from PyQt4.QtGui import *
from PyQt4.QtCore import *

from PyQt4 import QtGui, QtCore



class MainWindow(QMainWindow,Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.tableWidget.clicked.connect(self.hello)

    def hello(self,item):
        #print(item.column())
        if item.column()==0 :
            print("success")
            #I want to add this List at this cell of table
            itemN = QtGui.QListWidget()
            #hlayout = QtGui.QHBoxLayout()
            #hlayout.addWidget(itemN)
            #self.setCentralWidget(itemN)


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = MainWindow()
    w.show()
    sys.exit(app.exec_())

Any help would be appreciated. Thanks

my untitled.py code is here which generates a table in a window

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'untitled.ui'
#
# Created by: PyQt4 UI code generator 4.11.4
#
# WARNING! All changes made in this file will be lost!

from PyQt4 import QtCore, QtGui

try:
    _fromUtf8 = QtCore.QString.fromUtf8
except AttributeError:
    def _fromUtf8(s):
        return s

try:
    _encoding = QtGui.QApplication.UnicodeUTF8
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig, _encoding)
except AttributeError:
    def _translate(context, text, disambig):
        return QtGui.QApplication.translate(context, text, disambig)

class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName(_fromUtf8("MainWindow"))
        MainWindow.resize(800, 600)
        self.centralwidget = QtGui.QWidget(MainWindow)
        self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
        self.gridLayout = QtGui.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
        self.tableWidget = QtGui.QTableWidget(self.centralwidget)
        self.tableWidget.setObjectName(_fromUtf8("tableWidget"))
        self.tableWidget.setColumnCount(4)
        self.tableWidget.setRowCount(13)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(0, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(1, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(2, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(3, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(4, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(5, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(6, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(7, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(8, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(9, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(10, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(11, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setVerticalHeaderItem(12, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(0, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(1, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(2, item)
        item = QtGui.QTableWidgetItem()
        self.tableWidget.setHorizontalHeaderItem(3, item)
        self.gridLayout.addWidget(self.tableWidget, 0, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtGui.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 31))
        self.menubar.setObjectName(_fromUtf8("menubar"))
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtGui.QStatusBar(MainWindow)
        self.statusbar.setObjectName(_fromUtf8("statusbar"))
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
        item = self.tableWidget.verticalHeaderItem(0)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(1)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(2)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(3)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(4)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(5)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(6)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(7)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(8)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(9)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(10)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(11)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.verticalHeaderItem(12)
        item.setText(_translate("MainWindow", "New Row", None))
        item = self.tableWidget.horizontalHeaderItem(0)
        item.setText(_translate("MainWindow", "a", None))
        item = self.tableWidget.horizontalHeaderItem(1)
        item.setText(_translate("MainWindow", "b", None))
        item = self.tableWidget.horizontalHeaderItem(2)
        item.setText(_translate("MainWindow", "New Column", None))
        item = self.tableWidget.horizontalHeaderItem(3)
        item.setText(_translate("MainWindow", "d", None))


if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
Sahil Jain
  • 450
  • 1
  • 8
  • 19

2 Answers2

1

To get the position of the current cell we use the columnViewportPosition() and rowViewportPosition() methods that return the position x, y of the row and column respectively with respect to the QTableWidget viewport(), then we get the global position using the mapToGlobal() method, we will add the height of the cell to move it vertically.

It creates a Popup for it is going to use a QDialog where the QListWidget will be placed, this widget returns the selected text.

class PopUp(QDialog):
    def __init__(self, labels):
        QDialog.__init__(self, None, Qt.Popup | Qt.FramelessWindowHint)
        self.itemSelected = ""
        self.setLayout(QVBoxLayout())
        lWidget = QListWidget(self)
        self.layout().addWidget(lWidget)
        lWidget.addItems(labels)
        lWidget.itemClicked.connect(self.onItemClicked)
        self.layout().setContentsMargins(0, 0, 0, 0)

    def onItemClicked(self, item):
        self.itemSelected = item.text()
        self.accept()

    def text(self):
        return self.itemSelected


class MainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)
        self.setupUi(self)
        self.tableWidget.clicked.connect(self.onClicked)

    def onClicked(self, index):
        row = index.row()
        column = index.column()
        x = self.tableWidget.columnViewportPosition(column)
        y = self.tableWidget.rowViewportPosition(row) + self.tableWidget.rowHeight(row)
        pos = self.tableWidget.viewport().mapToGlobal(QPoint(x, y))
        p = PopUp(["1", "2", "3", "4", "5"])
        p.move(pos)
        if p.exec_() == QDialog.Accepted:
            t_item = QTableWidgetItem(p.text())
            self.tableWidget.setItem(row, column, t_item)

Screenshot:

enter image description here

eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • i am having a problem that i can't leave the dialog untill i select an item from it..can't we close dialog if we click outside it? and return control in main window? – Sahil Jain Oct 22 '17 at 09:08
  • You sure, implement this popup with QDialog especially so that when you click outside the QTableWidget it will close automatically. Are you using my code only or have you modified it? – eyllanesc Oct 22 '17 at 09:15
  • What is your OS? version of PyQt4 libraries? – eyllanesc Oct 22 '17 at 09:17
  • An image will not be used to check the error, save a video and upload it to drive, dropbox or similar and share the link here – eyllanesc Oct 22 '17 at 09:20
  • yea was thinking of same lol give me a min to get a video recorder – Sahil Jain Oct 22 '17 at 09:20
  • Run it from the cmd, and send me a similar video. IDEs can generate unwanted behaviors. – eyllanesc Oct 22 '17 at 09:34
  • anything on this sir? – Sahil Jain Oct 22 '17 at 10:12
  • one thing i could do is that i add a none option in list which when selected the data wouldn't go in table but the problem still stands for closing :p – Sahil Jain Oct 22 '17 at 10:15
  • Clicking outside the window I'm trying to correct because I have the same behavior, but in my case when I click on the empty space of the QtableWidget if the window is closed. Does a query attempt to close it with the ESCAPE key? – eyllanesc Oct 22 '17 at 10:15
0

I think the function you are looking for is:

self.tableWidget.setCellWidget(rowNum, colNum, itemN)

Where rowNum and colNum is the position, so 0,0 will put it in the upper left box. itemN is the QListWidget you made.

Here is a reference: http://pyqt.sourceforge.net/Docs/PyQt4/qtablewidget.html#setCellWidget

And here is a related question: Adding widgets to qtablewidget pyqt

After looking at your screenshots I see the object you want is a QComboBox, not a QlistWidget. Link: http://doc.qt.io/qt-4.8/qcombobox.html

You'll want to use the original function I mentioned to fill an element of the table with a combobox instead of a listWidget. And then use addItems to fill the combobox with options. And then use currentText to see what option the user has selected.

If that doesn't sound like what you want, you'll have to make a custom version of the tableWidget that has the functionality you want. That is more complicated and I can't cover that all in a single answer. But if you have more questions I can try to point you in the right direction.

wsad597
  • 53
  • 8