Add combobox to horizontal header in QTableWidget - python

I want to create a table in PyQt5 that has a combobox in each column header. When I try to do it, the following error is returned:
TypeError: setHorizontalHeaderItem(self, int, QTableWidgetItem): argument 2 has unexpected type 'QComboBox'
Apparently the function setHorizontalHeaderItem() doesn't accept widgets as items. So is there a way to achieve this? If not, I would settle with putting the comboboxes above the headers, but they should be aligned with the size of each column, even if the user changes the width with the mouse. I don't know if this is possible either.
My code:
from PyQt5 import QtWidgets
import numpy as np
class App(QtWidgets.QWidget):
def __init__(self):
super(App,self).__init__()
self.data = np.random.rand(5,5)
self.createTable()
self.layout = QtWidgets.QVBoxLayout()
self.layout.addWidget(self.table)
self.setLayout(self.layout)
self.showMaximized()
def createTable(self):
self.header = []
self.table = QtWidgets.QTableWidget(len(self.data), len(self.data[0]))
for i in range(len(self.data[0])):
self.header.append(QtWidgets.QComboBox())
self.header[-1].addItem('Variable')
self.header[-1].addItem('Timestamp')
self.table.setHorizontalHeaderItem(i,self.header[-1])
for i in range(len(self.data)):
for j in range(len(self.data[0])):
self.table.setItem(i,j,QtWidgets.QTableWidgetItem(str(self.data[i][j])))
if __name__ == '__main__':
app = QtWidgets.QApplication([])
ex = App()
app.exec_()

QHeaderView does not support widgets as items so you must create a custom header as I show below:
from PyQt5 import QtCore, QtWidgets
import numpy as np
class HorizontalHeader(QtWidgets.QHeaderView):
def __init__(self, values, parent=None):
super(HorizontalHeader, self).__init__(QtCore.Qt.Horizontal, parent)
self.setSectionsMovable(True)
self.comboboxes = []
self.sectionResized.connect(self.handleSectionResized)
self.sectionMoved.connect(self.handleSectionMoved)
def showEvent(self, event):
for i in range(self.count()):
if i < len(self.comboboxes):
combo = self.comboboxes[i]
combo.clear()
combo.addItems(["Variable", "Timestamp"])
else:
combo = QtWidgets.QComboBox(self)
combo.addItems(["Variable", "Timestamp"])
self.comboboxes.append(combo)
combo.setGeometry(self.sectionViewportPosition(i), 0, self.sectionSize(i)-4, self.height())
combo.show()
if len(self.comboboxes) > self.count():
for i in range(self.count(), len(self.comboboxes)):
self.comboboxes[i].deleteLater()
super(HorizontalHeader, self).showEvent(event)
def handleSectionResized(self, i):
for i in range(self.count()):
j = self.visualIndex(i)
logical = self.logicalIndex(j)
self.comboboxes[i].setGeometry(self.sectionViewportPosition(logical), 0, self.sectionSize(logical)-4, self.height())
def handleSectionMoved(self, i, oldVisualIndex, newVisualIndex):
for i in range(min(oldVisualIndex, newVisualIndex), self.count()):
logical = self.logicalIndex(i)
self.comboboxes[i].setGeometry(self.ectionViewportPosition(logical), 0, self.sectionSize(logical) - 5, height())
def fixComboPositions(self):
for i in range(self.count()):
self.comboboxes[i].setGeometry(self.sectionViewportPosition(i), 0, self.sectionSize(i) - 5, self.height())
class TableWidget(QtWidgets.QTableWidget):
def __init__(self, *args, **kwargs):
super(TableWidget, self).__init__(*args, **kwargs)
header = HorizontalHeader(self)
self.setHorizontalHeader(header)
def scrollContentsBy(self, dx, dy):
super(TableWidget, self).scrollContentsBy(dx, dy)
if dx != 0:
self.horizontalHeader().fixComboPositions()
class App(QtWidgets.QWidget):
def __init__(self):
super(App,self).__init__()
self.data = np.random.rand(10, 10)
self.createTable()
layout = QtWidgets.QVBoxLayout(self)
layout.addWidget(self.table)
self.showMaximized()
def createTable(self):
self.header = []
self.table = TableWidget(*self.data.shape)
for i, row_values in enumerate(self.data):
for j, value in enumerate(row_values):
self.table.setItem(i, j, QtWidgets.QTableWidgetItem(str(value)))
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
ex = App()
sys.exit(app.exec_())

Related

pyside2 how to query and create and delete dynamic widget

layout
layout (1)
QlineEdit
Qpushbutton
layout (2)
QlineEdit
Qpushbutton
Qpushbutton (3)
I try to create and delete layout(1,2) in layout.
it's work real time. layout(1,2) are dynamic number (1,2,3,~~)
Qpushbutton click -> parent layout and widget delete
and query text in QlineEdit
my test code --
#-*- coding:utf-8 -*-
import maya.cmds as mc
import os
import pprint
from PySide2 import QtWidgets, QtCore, QtGui
class PreferenceUI(QtWidgets.QDialog):
def __init__(self):
super(PreferenceUI, self).__init__()
self.setWindowTitle("preference")
self.create_widgets()
self.create_layouts()
self.create_connections()
self.load_department()
def create_widgets(self):
self.departmentNameLine = QtWidgets.QLineEdit()
self.departmentNameLine.setFixedSize(100,20)
self.departmentPathLine = QtWidgets.QLineEdit()
self.departmentMinusBtn = QtWidgets.QPushButton("-")
self.departmentMinusBtn.setFixedSize(20,20)
self.departmentPlusBtn = QtWidgets.QPushButton("+")
self.sysAppendWidget = QtWidgets.QTextEdit()
def create_layouts(self):
self.mainLayout = QtWidgets.QFormLayout(self)
self.departmentLayout = QtWidgets.QVBoxLayout()
self.departmentLastLayout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(self.departmentLastLayout)
self.departmentLayout.addWidget(self.departmentPlusBtn)
self.mainLayout.addRow("department :", self.departmentLayout)
self.mainLayout.insertRow(self.mainLayout.count()-1, "sys.path.append :", self.sysAppendWidget)
def create_connections(self):
pass
def load_department(self):
self.departmentPlusBtn.setParent(None)
jsonDict = {"department": [["temp", "tempPath"], ["temp2", "temp2Path"]]}
for i in range(len(jsonDict["department"])):
layout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(layout)
departmentNameLine = QtWidgets.QLineEdit()
departmentNameLine.setText(jsonDict["department"][i][0])
departmentNameLine.setFixedSize(100,20)
departmentPathLine = QtWidgets.QLineEdit()
departmentPathLine.setText(jsonDict["department"][i][1])
departmentMinusBtn = QtWidgets.QPushButton("-")
departmentMinusBtn.setFixedSize(20,20)
cnt = self.departmentLayout.count()
departmentMinusBtn.clicked.connect(lambda x:self.remove_department(cnt))
layout.addWidget(departmentNameLine)
layout.addWidget(departmentPathLine)
layout.addWidget(departmentMinusBtn)
self.departmentLayout.insertWidget(self.departmentLayout.count(), self.departmentPlusBtn)
def remove_department(self, index):
print index
print self.departmentLayout.children()[0].layout().children()
if __name__ == "__main__":
try:
ui.close
except:
pass
ui = PreferenceUI()
ui.show()
I want
add path line
delete path line
query departmentNameLine, departmentPathLine text
i try ↑, but fail
i try in maya
To keep the logic tidy I have created a class that represents a row, then store the rows in a list to get the texts or to delete the row as I show below:
from functools import partial
from PySide2 import QtWidgets, QtCore, QtGui
class Widget(QtWidgets.QWidget):
def __init__(self, text1, text2, parent=None):
super().__init__(parent)
self.departmentNameLine = QtWidgets.QLineEdit(text1)
self.departmentNameLine.setFixedSize(100, 20)
self.departmentPathLine = QtWidgets.QLineEdit(text2)
self.departmentMinusBtn = QtWidgets.QPushButton("-")
self.departmentMinusBtn.setFixedSize(20, 20)
self.setContentsMargins(0, 0, 0, 0)
layout = QtWidgets.QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
layout.addWidget(self.departmentNameLine)
layout.addWidget(self.departmentPathLine)
layout.addWidget(self.departmentMinusBtn)
class PreferenceUI(QtWidgets.QDialog):
def __init__(self):
super(PreferenceUI, self).__init__()
self.widgets = []
self.setWindowTitle("preference")
self.create_widgets()
self.create_layouts()
self.create_connections()
self.load_department()
def create_widgets(self):
self.departmentPlusBtn = QtWidgets.QPushButton("+")
self.sysAppendWidget = QtWidgets.QTextEdit()
def create_layouts(self):
self.mainLayout = QtWidgets.QFormLayout(self)
self.departmentLayout = QtWidgets.QVBoxLayout()
self.departmentLastLayout = QtWidgets.QHBoxLayout()
self.departmentLayout.addLayout(self.departmentLastLayout)
self.departmentLayout.addWidget(self.departmentPlusBtn)
self.mainLayout.addRow("department :", self.departmentLayout)
self.mainLayout.insertRow(
self.mainLayout.count() - 1, "sys.path.append :", self.sysAppendWidget
)
def create_connections(self):
self.departmentPlusBtn.clicked.connect(self.add_row)
def load_department(self):
jsonDict = {"department": [["temp", "tempPath"], ["temp2", "temp2Path"]]}
for text1, text2 in jsonDict["department"]:
self.create_row(text1, text2)
def save_departament(self):
l = []
for widget in self.widgets:
l.append([self.departmentNameLine.text(), self.departmentPathLine.text()])
jsonDict = {"department": l}
print(jsonDict)
def add_row(self):
self.create_row("text1", "text2")
def create_row(self, text1="", text2=""):
widget = Widget(text1, text2)
widget.departmentMinusBtn.clicked.connect(partial(self.delete, widget))
self.departmentLayout.addWidget(widget)
self.widgets.append(widget)
def delete(self, widget):
if widget in self.widgets:
self.widgets.remove(widget)
widget.deleteLater()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = PreferenceUI()
w.show()
sys.exit(app.exec_())

How to add dropdown menu to QMessageBox?

After looking at some code I found on stackoverflow, I was able to find a way to add a table to a QmessageBox. Now that I have done that, I would like to place a drop down menu in the top right of the QmessageBox and I cannot figure out a way to do that (if it even is possible).
Here is my edited code:
from PyQt4.QtGui import *
from PyQt4.Qt import *
import sys
class MyMessageBox(QMessageBox):
def __init__(self):
QMessageBox.__init__(self)
self.setSizeGripEnabled (True)
self.setWindowTitle('Get Parent Script')
self.setIcon(self.Question)
#self.setText("Hello MessageBox")
self.addButton("Select", QMessageBox.ActionRole)
self.setStandardButtons(QMessageBox.Cancel)
#self.addWidget(QInputDialog())
self.addTableWidget (self)
currentClick = self.exec_()
def addTableWidget (self, parentItem) :
self.l = QVBoxLayout()
self.tableWidget = QTableWidget(parentItem)
self.tableWidget.setObjectName ('tableWidget')
self.tableWidget.setColumnCount(3)
self.tableWidget.setRowCount(2)
self.tableWidget.setHorizontalHeaderLabels(QString("Nuke Script;File Modification Time;User").split(";"))
header = self.tableWidget.horizontalHeader()
header.setResizeMode(0, QHeaderView.ResizeToContents)
header.setResizeMode(1, QHeaderView.Stretch)
header.setResizeMode(2, QHeaderView.Stretch)
stringlist = {u'/SEQ/ZZ/ZZ_012_001/Comp/nuke/scripts/comp':u'user1', u'/SEQ/ZZ/ZZ_012_001/Comp/nuke/scripts/comp/hello': u'user2'}
row = 0
for key, value in stringlist.iteritems():
print key, value
nameitem = QTableWidgetItem(str(key))
codeitem = QTableWidgetItem(str(value))
self.tableWidget.setItem(row,0,nameitem)
self.tableWidget.setItem(row,1,codeitem)
row +=1
self.tableWidget.resize(1000, 170)
self.l.addWidget(self.tableWidget)
self.setLayout(self.l)
def event(self, e):
result = QMessageBox.event(self, e)
self.setMinimumWidth(0)
self.setMaximumWidth(16777215)
self.setMinimumHeight(0)
self.setMaximumHeight(16777215)
self.setSizePolicy(
QSizePolicy.Expanding,
QSizePolicy.Expanding
)
self.resize(1000, 300)
return result
def run_cli():
#app = QtWidgets.QApplication(sys.argv)
app = QApplication(sys.argv)
MyMessageBox()
if __name__ == '__main__':
run_cli()
In your case it is not optimal to use QMessageBox since I involve unnecessary work because this widget already has a predefined layout, instead you can create a widget based on a QDialog:
from PyQt4 import QtCore, QtGui
class Dialog(QtGui.QDialog):
def __init__(self, parent=None):
super(Dialog, self).__init__(parent)
label = QtGui.QLabel("Text")
combo = QtGui.QComboBox()
combo.addItems(["option1", "option2", "option3"])
self.tableWidget = QtGui.QTableWidget(2, 3)
self.tableWidget.setHorizontalHeaderLabels(
QtCore.QString("Nuke Script;File Modification Time;User").split(";")
)
header = self.tableWidget.horizontalHeader()
header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
header.setResizeMode(1, QtGui.QHeaderView.Stretch)
header.setResizeMode(2, QtGui.QHeaderView.Stretch)
stringlist = {
u"/SEQ/ZZ/ZZ_012_001/Comp/nuke/scripts/comp": u"user1",
u"/SEQ/ZZ/ZZ_012_001/Comp/nuke/scripts/comp/hello": u"user2",
}
for row, (key, value) in enumerate(stringlist.iteritems()):
nameitem = QtGui.QTableWidgetItem(str(key))
codeitem = QtGui.QTableWidgetItem(str(value))
self.tableWidget.setItem(row, 0, nameitem)
self.tableWidget.setItem(row, 1, codeitem)
box = QtGui.QDialogButtonBox(
QtGui.QDialogButtonBox.Ok | QtGui.QDialogButtonBox.Cancel,
centerButtons=True,
)
box.accepted.connect(self.accept)
box.rejected.connect(self.reject)
lay = QtGui.QGridLayout(self)
lay.addWidget(label, 0, 0)
lay.addWidget(combo, 0, 1)
lay.addWidget(self.tableWidget, 1, 0, 1, 2)
lay.addWidget(box, 2, 0, 1, 2)
self.resize(640, 240)
def run_cli():
import sys
app = QtGui.QApplication(sys.argv)
w = Dialog()
w.exec_()
if __name__ == "__main__":
run_cli()

MouseMove event on cell in Qtablewidget to display or print a message

I have QTablewidget and I want to use a mousemoveevent on a particular cell B. When mouse moves over this cell B, a message would appear or be printed. I have created the constructor, but it really does not work. Every thing is allright expect from those lines of code.
def mouseMoveEvent(self, event):
it = self.item(self.rowCount(),1)
it.QToolTip.showText('Insert')
self.onHovered()
Keep in mind that Qtooltip is assigned when the cell is clicked and works. But I want to do this by MouseMoveevent. Maybe my constructor of MouseEvent code is not right.
Expecting to behave.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
def copy_widget(w):
if isinstance(w, QtWidgets.QWidget):
new_w = type(w)()
if isinstance(w, QtWidgets.QComboBox):
vals = [w.itemText(ix) for ix in range(w.count())]
new_w.addItems(vals)
return new_w
class LoadTable(QtWidgets.QTableWidget):
def __init__(self, parent=None):
super(LoadTable, self).__init__(1, 5, parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
headertitle = ("A","B","C","D","E")
self.setHorizontalHeaderLabels(headertitle)
self.verticalHeader().hide()
self.horizontalHeader().setHighlightSections(False)
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)
self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.setColumnWidth(0, 130)
combox_lay = QtWidgets.QComboBox(self)
combox_lay.addItems(["I","II"])
self.setCellWidget(0, 4, combox_lay)
self.cellChanged.connect(self._cellclicked)
#QtCore.pyqtSlot(int, int)
def _cellclicked(self, r, c):
it = self.item(r, c)
it.setTextAlignment(QtCore.Qt.AlignCenter)
n_it = self.item(r,1)
n_it.setToolTip('Test')
#QtCore.pyqtSlot()
def _addrow(self):
rowcount = self.rowCount()
self.insertRow(rowcount)
combox_add = QtWidgets.QComboBox(self)
combox_add.addItems(["I","II"])
self.setCellWidget(rowcount, 4, combox_add)
#QtCore.pyqtSlot()
def _removerow(self):
if self.rowCount() > 0:
self.removeRow(self.rowCount()-1)
#QtCore.pyqtSlot()
def _copyrow(self):
r = self.currentRow()
if 0 <= r < self.rowCount():
cells = {"items": [], "widgets": []}
for i in range(self.columnCount()):
it = self.item(r, i)
if it:
cells["items"].append((i, it.clone()))
w = self.cellWidget(r, i)
if w:
cells["widgets"].append((i, copy_widget(w)))
self.copy(cells, r+1)
def copy(self, cells, r):
self.insertRow(r)
for i, it in cells["items"]:
self.setItem(r, i, it)
for i, w in cells["widgets"]:
self.setCellWidget(r, i, w)
def mouseMoveEvent(self, event):
it = self.item(self.rowCount(),1)
it.QToolTip.showText('Insert')
self.onHovered()
def onHovered(self):
print("Works")
class ThirdTabLoads(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ThirdTabLoads, self).__init__(parent)
table = LoadTable()
add_button = QtWidgets.QPushButton("Add")
add_button.clicked.connect(table._addrow)
delete_button = QtWidgets.QPushButton("Delete")
delete_button.clicked.connect(table._removerow)
copy_button = QtWidgets.QPushButton("Copy")
copy_button.clicked.connect(table._copyrow)
button_layout = QtWidgets.QVBoxLayout()
button_layout.addWidget(add_button, alignment=QtCore.Qt.AlignBottom)
button_layout.addWidget(delete_button, alignment=QtCore.Qt.AlignTop)
button_layout.addWidget(copy_button, alignment=QtCore.Qt.AlignTop)
tablehbox = QtWidgets.QHBoxLayout()
tablehbox.setContentsMargins(10, 10, 10, 10)
tablehbox.addWidget(table)
grid = QtWidgets.QGridLayout(self)
grid.addLayout(button_layout, 0, 1)
grid.addLayout(tablehbox, 0, 0)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = ThirdTabLoads()
w.show()
sys.exit(app.exec_())
The itemEntered signal must be used, but to do this, the mouseTracking must be enabled in addition to the item. When a row is added it does not imply that the items for each box exist so I have modified it to create it.
class LoadTable(QtWidgets.QTableWidget):
def __init__(self, parent=None):
super(LoadTable, self).__init__(0, 5, parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
headertitle = ("A","B","C","D","E")
self.setHorizontalHeaderLabels(headertitle)
self.verticalHeader().hide()
self.horizontalHeader().setHighlightSections(False)
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)
self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.setColumnWidth(0, 130)
self.setMouseTracking(True)
self.itemEntered.connect(self.on_itemEntered)
self._addrow()
def on_itemEntered(self, it):
QtWidgets.QToolTip.hideText()
if it.column() == 1:
r = self.visualItemRect(it)
p = self.viewport().mapToGlobal(QtCore.QPoint(r.center().x(), r.top()))
QtWidgets.QToolTip.showText(p, "Insert")
#QtCore.pyqtSlot()
def _addrow(self):
rowcount = self.rowCount()
self.insertRow(rowcount)
combox_add = QtWidgets.QComboBox(self)
combox_add.addItems(["I","II"])
self.setCellWidget(rowcount, 4, combox_add)
for c in range(self.columnCount()):
self.setItem(rowcount, c, QtWidgets.QTableWidgetItem())
# ...

QTreeView change selected items’ display text

How can I change the text displayed in the second column of the rows selected in the treeview when the user hits 'Edit' in the UI? I'm using python and pyside but I'm not clear on how to do this.
What I want to happen is: When user clicks Edit in the UI i would like it to change the text of the selected Treeview Rows second columns. You can just change the text to say 'Hello' or something simple.
import sys
from PySide import QtGui, QtCore
class SortModel(QtGui.QSortFilterProxyModel):
def __init__(self, *args, **kwargs):
super(SortModel, self).__init__(*args, **kwargs)
def lessThan(self, left, right):
leftData = self.sourceModel().data(left)
rightData = self.sourceModel().data(right)
if leftData:
leftData = leftData.lower()
if rightData:
rightData = rightData.lower()
print('L:', leftData, 'R:', rightData)
return leftData < rightData
class Browser(QtGui.QDialog):
def __init__(self, parent=None):
super(Browser, self).__init__(parent)
self.initUI()
def initUI(self):
self.resize(200, 300)
self.setWindowTitle('Assets')
self.setModal(True)
self.results = ""
self.uiItems = QtGui.QTreeView()
self.uiItems.setAlternatingRowColors(True)
self.uiItems.setSortingEnabled(True)
self.uiItems.sortByColumn(0, QtCore.Qt.AscendingOrder)
self.uiItems.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
self.uiItems.header().setResizeMode(QtGui.QHeaderView.ResizeToContents)
self.uiItems.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
self.uiItems.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self._model = self.create_model(self)
self._spmodel = SortModel(self)
self._spmodel.setSourceModel(self._model)
self._spmodel.setDynamicSortFilter(False)
self.uiItems.setModel(self._spmodel)
self.uiEdit = QtGui.QPushButton('Edit')
grid = QtGui.QGridLayout()
grid.setContentsMargins(0, 0, 0, 0)
grid.addWidget(self.uiItems, 0, 0)
grid.addWidget(self.uiEdit, 1, 0)
self.setLayout(grid)
self.uiItems.doubleClicked.connect(self.doubleClickedItem)
self.show()
def doubleClickedItem(self, idx):
name = idx.data(role=QtCore.Qt.DisplayRole)
model = idx.model()
model.setData(idx, 'great', role=QtCore.Qt.DisplayRole)
def create_model(self, parent):
items = [
'Cookie dough',
'Hummus',
'Spaghetti',
'Dal makhani',
'Chocolate whipped cream'
]
model = QtGui.QStandardItemModel()
model.setHorizontalHeaderLabels(['Name', 'Great'])
for item in items:
root = []
parentNode = QtGui.QStandardItem(item)
root.append(parentNode)
# add child row with 2 columns
for i in range(3):
row = []
col1 = QtGui.QStandardItem()
col1.setData('COLUMN 1', role=QtCore.Qt.DisplayRole)
row.append(col1)
col2 = QtGui.QStandardItem()
col2.setData('COLUMN 2', role=QtCore.Qt.DisplayRole)
row.append(col2)
parentNode.appendRow(row)
model.appendRow(root)
return model
def showEvent(self, event):
geom = self.frameGeometry()
geom.moveCenter(QtGui.QCursor.pos())
self.setGeometry(geom)
super(Browser, self).showEvent(event)
def keyPressEvent(self, event):
if event.key() == QtCore.Qt.Key_Escape:
# self.hide()
self.close()
event.accept()
else:
super(Browser, self).keyPressEvent(event)
def main():
app = QtGui.QApplication(sys.argv)
ex = Browser()
sys.exit(app.exec_())
if __name__ == '__main__':
main()
Connect the button’s clicked signal, retrieve the selected items via model.selectedIndexes, iterate over them and only handle those with .column()== 1 as in your doubleClickedItem function.
You can also change the SelectionBehavior to only select single items instead of complete rows.

How do I get the contents of a row of QTableWidget with click on the button in python and PyQt

If i click on any of the edit buttons, how do I get the contents of cells in the same row?
class EditButtonsWidget(QtGui.QWidget):
def __init__(self, parent=None):
super(EditButtonsWidget,self).__init__(parent)
btnsave = QtGui.QPushButton('Save')
btnedit = QtGui.QPushButton('edit')
btndelete = QtGui.QPushButton('delete')
layout = QtGui.QHBoxLayout()
layout.setContentsMargins(0,0,0,0)
layout.setSpacing(0)
layout.addWidget(btnsave)
layout.addWidget(btnedit)
layout.addWidget(btndelete)
self.setLayout(layout)
class MainForm(QDialog):
def __init__(self,parent=None):
super(MainForm,self).__init__(parent)
self.resize(400,200)
self.tableWidget = QTableWidget()
layout = QVBoxLayout()
layout.addWidget( self.tableWidget)
self.setLayout(layout)
self.init_main_form()
def bb(self):
button = QtGui.QApplication.focusWidget()
index = self.tableWidget.indexAt(button.pos())
if index.isValid():
print(index.row(), index.column())
def init_main_form(self):
data =[['a','b','c','d'],['z','y','x','w']]
self.tableWidget.setColumnCount(5)
for row in data:
inx = data.index(row)
self.tableWidget.insertRow(inx)
self.tableWidget.setItem(inx,0,QTableWidgetItem(str(row[0])))
self.tableWidget.setItem(inx,1,QTableWidgetItem(str(row[1])))
self.tableWidget.setItem(inx,2,QTableWidgetItem(str(row[2])))
self.tableWidget.setItem(inx,3,QTableWidgetItem(str(row[3])))
self.tableWidget.setCellWidget(inx,4,EditButtonsWidget())
def main():
app = QApplication(sys.argv)
main_form = MainForm()
main_form.show()
app.exec_()
if __name__ == '__main__':
main()
Implemented signals and slots and now you will get idea how you can handle it
And mixing imports is not really a good idea
from PyQt4 import QtCore, QtGui
import sys
class EditButtonsWidget(QtGui.QWidget):
editCalled = QtCore.pyqtSignal(str)
def __init__(self, row, col, parent=None,):
super(EditButtonsWidget,self).__init__(parent)
self.row = row
self.col = col
self.parent = parent
btnsave = QtGui.QPushButton('Save')
btnedit = QtGui.QPushButton('edit')
btndelete = QtGui.QPushButton('delete')
layout = QtGui.QHBoxLayout()
layout.setContentsMargins(0,0,0,0)
layout.setSpacing(0)
layout.addWidget(btnsave)
layout.addWidget(btnedit)
layout.addWidget(btndelete)
self.setLayout(layout)
btnedit.clicked.connect(self.getAllCellVal)
#QtCore.pyqtSlot()
def getAllCellVal(self):
itmVal = {}
for col in range(0, 4):
itm = self.parent.item(self.row, col).text()
itmVal[col] = str(itm)
if itmVal:
self.editCalled.emit(str(itmVal))
class MainForm(QtGui.QDialog):
def __init__(self,parent=None):
super(MainForm,self).__init__(parent)
self.resize(400,200)
self.tableWidget = QtGui.QTableWidget()
layout = QtGui.QVBoxLayout()
layout.addWidget( self.tableWidget)
self.setLayout(layout)
self.init_main_form()
def bb(self):
button = QtGui.QApplication.focusWidget()
index = self.tableWidget.indexAt(button.pos())
if index.isValid():
print(index.row(), index.column())
def printEditVal(self, values):
print values
def init_main_form(self):
data =[['a','b','c','d'],['z','y','x','w']]
self.tableWidget.setColumnCount(5)
for row in data:
inx = data.index(row)
self.tableWidget.insertRow(inx)
self.tableWidget.setItem(inx,0,QtGui.QTableWidgetItem(str(row[0])))
self.tableWidget.setItem(inx,1,QtGui.QTableWidgetItem(str(row[1])))
self.tableWidget.setItem(inx,2,QtGui.QTableWidgetItem(str(row[2])))
self.tableWidget.setItem(inx,3,QtGui.QTableWidgetItem(str(row[3])))
buttonWid = EditButtonsWidget(inx,4, self.tableWidget)
buttonWid.editCalled.connect(self.printEditVal)
self.tableWidget.setCellWidget(inx,4,buttonWid)
def main():
app = QtGui.QApplication(sys.argv)
main_form = MainForm()
main_form.show()
app.exec_()
if __name__ == '__main__':
main()

Categories

Resources