Add qcheckbox in every row of qtablewidget - python

I'm trying to add a checkbox in each row of a qtablewidget. When the table has more than one row, the checkbox is not inserted in the first row. Just in the last one. But the data coming from a db are inserted in every row. Can anyone please explain what I am doing wrong here.
checkbox = QtWidgets.QCheckBox()
income = helper.selectOne("""SELECT En_Kat.ID_En, En_Kat.ID_Kind, En_Kat.Entgelt_Kat, En_Kat.E_Start_Date
From En_Kat WHERE En_Kat.ID_Kind = ?""", (idc, ))
for rowi, i in enumerate(income):
self.ui.incomeTWG.insertRow(rowi)
self.ui.incomeTWG.setCellWidget(rowi,5,checkbox)
for coli, datai in enumerate(i):
celli = QtWidgets.QTableWidgetItem(str(datai))
self.ui.incomeTWG.setItem(rowi,coli,celli)
celli.setTextAlignment(Qt.AlignHCenter)
Now with reproducable code:
import sys
from ui.mainwindow import Ui_MainWindow
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt
app = QtWidgets.QApplication(sys.argv)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
checkbox = QtWidgets.QCheckBox()
income = (('1', '2'),('3','4'))
for rowi, i in enumerate(income):
self.ui.tableWidget.insertRow(rowi)
self.ui.tableWidget.setCellWidget(rowi,2,checkbox)
for coli, datai in enumerate(i):
celli = QtWidgets.QTableWidgetItem(str(datai))
self.ui.tableWidget.setItem(rowi,coli,celli)
celli.setTextAlignment(Qt.AlignHCenter)
window = MainWindow()
window.show()
sys.exit(app.exec_())
and here is the ui:
efrom PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(230, 160, 351, 192))
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(3)
self.tableWidget.setRowCount(0)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(2, item)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 30))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "a"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "b"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "c"))

In your code you have only created a single QCheckBox, and what happens is that if you set a widget to a certain item and that widget was already in another widget then it will be moved, another widget will not be created as you expect. The solution is to create widgets inside the loop:
income = (("1", "2"), ("3", "4"))
for rowi, i in enumerate(income):
checkbox = QtWidgets.QCheckBox()
self.ui.tableWidget.insertRow(rowi)
self.ui.tableWidget.setCellWidget(rowi, 2, checkbox)
for coli, datai in enumerate(i):
celli = QtWidgets.QTableWidgetItem(str(datai))
self.ui.tableWidget.setItem(rowi, coli, celli)
celli.setTextAlignment(Qt.AlignHCenter)

Related

How to show description of item selected in column view?

I'm unfamiliar with PyQt and QColumnView, how do I make it so that we get a "description" of whatever the user selects and not another row of items that I can click on extending the column view?
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(423, 390)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.add_btn = QtWidgets.QPushButton(self.centralwidget)
self.add_btn.setGeometry(QtCore.QRect(334, 345, 75, 23))
self.add_btn.setObjectName("add_btn")
self.auto_btn = QtWidgets.QPushButton(self.centralwidget)
self.auto_btn.setGeometry(QtCore.QRect(245, 345, 81, 23))
self.auto_btn.setObjectName("auto_btn")
self.auto_num = QtWidgets.QLineEdit(self.centralwidget)
self.auto_num.setGeometry(QtCore.QRect(141, 346, 99, 20))
self.auto_num.setText("")
self.auto_num.setClearButtonEnabled(False)
self.auto_num.setObjectName("auto_num")
self.columnView = QtWidgets.QColumnView(self.centralwidget)
self.columnView.setGeometry(QtCore.QRect(10, 10, 399, 320))
self.columnView.setObjectName("columnView")
model = QtGui.QStandardItemModel()
for i in 'abcd':
group = QtGui.QStandardItem(i)
model.appendRow(group)
self.columnView.setModel(model)
MainWindow.setCentralWidget(self.centralwidget)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.add_btn.setText(_translate("MainWindow", "Add Item"))
self.auto_btn.setText(_translate("MainWindow", "Auto-populate"))
this is how i want it to appear
I don't need to use QColumnView, just QListView + QTextEdit and associate a role for the description, so when the selection changes, change the text shown in the QTextEdit.
from PyQt5 import QtCore, QtGui, QtWidgets
DescriptionRole = QtCore.Qt.UserRole + 1000
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super().__init__(parent)
self.listview = QtWidgets.QListView()
self.textedit = QtWidgets.QTextEdit(readOnly=True)
self.model = QtGui.QStandardItemModel()
self.listview.setModel(self.model)
data = [
("a", "description of 'a'"),
("b", "description of 'b'"),
("c", "description of 'c'"),
("d", "description of 'd'"),
]
for text, description in data:
group = QtGui.QStandardItem(text)
group.setData(description, DescriptionRole)
self.model.appendRow(group)
self.listview.selectionModel().selectionChanged.connect(
self.on_selection_changed
)
central_widget = QtWidgets.QWidget()
self.setCentralWidget(central_widget)
hlay = QtWidgets.QHBoxLayout(central_widget)
hlay.addWidget(self.listview)
hlay.addWidget(self.textedit)
#QtCore.pyqtSlot()
def on_selection_changed(self):
indexes = self.listview.selectedIndexes()
if indexes:
index = indexes[0]
description = index.data(DescriptionRole)
self.textedit.setPlainText(description)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())

How to resize horizontal qtabwidget

I'm following the instruction of this post but I have a problem with the size of the tabwidgets. I would like to adjust it to the size of the text.
I have add an exemple of code where the size of the tab doesn't match with the size of the labels :
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(800, 600)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tabWidget = TabWidget(self.centralwidget)
self.tabWidget.setGeometry(QtCore.QRect(60, 30, 581, 481))
self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
self.tabWidget.addTab(self.tab, "")
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
self.tabWidget.addTab(self.tab_2, "")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 22))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tabWidget.setCurrentIndex(1)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Case 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Case 2"))
from tabwidget import TabWidget
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
And here is the tabwidget.py which is provided in this post
from PyQt5 import QtGui, QtWidgets, QtCore
class HorizontalTabBar(QtWidgets.QTabBar):
def paintEvent(self, event):
painter = QtWidgets.QStylePainter(self)
option = QtWidgets.QStyleOptionTab()
for index in range(self.count()):
self.initStyleOption(option, index)
painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, option)
painter.drawText(self.tabRect(index),
QtCore.Qt.AlignCenter | QtCore.Qt.TextDontClip,
self.tabText(index))
def tabSizeHint(self, index):
size = QtWidgets.QTabBar.tabSizeHint(self, index)
if size.width() < size.height():
size.transpose()
return size
class TabWidget(QtWidgets.QTabWidget):
def __init__(self, parent=None):
QtWidgets.QTabWidget.__init__(self, parent)
self.setTabBar(HorizontalTabBar())

How to send a signal from a qtableWidget horizontal header?

I want to remove a row from a qtableWidget when selecting an horizontal header.
I tried the following command but it's not working with pyqt5 :
tableWidget.horizontalHeader().sectionClicked.connect(MyCallable)
In fact, Qt documentation does not mention this signal for a qTableWidget. So I am looking for an equivalent function i.e a function that will send a notification when an horizontal header is selected.
Below, a reproducible example :
from PyQt5 import QtCore, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(350, 250)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(20, 20, 300, 200))
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(2)
self.tableWidget.setRowCount(2)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
# =============================================================================
self.tableWidget.horizontalHeader().sectionClicked.connect(self.call)
# =============================================================================
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 200, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "First name"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "Surname"))
it = QtWidgets.QTableWidgetItem("John")
self.tableWidget.setItem(0, 0, it)
it = QtWidgets.QTableWidgetItem("Heen")
self.tableWidget.setItem(0, 1, it)
it = QtWidgets.QTableWidgetItem("Mark")
self.tableWidget.setItem(1, 0, it)
it = QtWidgets.QTableWidgetItem("Thomson")
self.tableWidget.setItem(1, 1, it)
def call(self):
print("row selected")
if __name__ == "__main__":
import sys
if not QtWidgets.QApplication.instance():
app = QtWidgets.QApplication(sys.argv)
else:
app = QtWidgets.QApplication.instance()
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
app.exec_()
sys.exit(app.exec_())

how to make a particular column in QTreeWidget integer/Float, such that the user can't enter any alphabets or symbols instead of integers/Floats?

I am making a GUI in PyQt5 which uses QTreeWidget. I want a particular column to be integer only column. The user shouldn't be able to enter any non integer item in it. I saw some methods using QVariant but it doesn't seem to fullfill my requirement.
Here is what I found!
.But this seems to me like setting the data from the back-end not from the user side.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(478, 320)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.centralwidget)
self.verticalLayout.setObjectName("verticalLayout")
self.treeWidget = QtWidgets.QTreeWidget(self.centralwidget)
self.treeWidget.setAlternatingRowColors(True)
self.treeWidget.setObjectName("treeWidget")
item_0 = QtWidgets.QTreeWidgetItem(self.treeWidget)
item_1 = QtWidgets.QTreeWidgetItem(item_0)
item_1.setFlags(QtCore.Qt.ItemIsSelectable|QtCore.Qt.ItemIsEditable|QtCore.Qt.ItemIsDragEnabled|QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled)
self.verticalLayout.addWidget(self.treeWidget)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 478, 20))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.treeWidget.headerItem().setText(0, _translate("MainWindow", "Some other data"))
self.treeWidget.headerItem().setText(1, _translate("MainWindow", "Only Integers"))
__sortingEnabled = self.treeWidget.isSortingEnabled()
self.treeWidget.setSortingEnabled(False)
self.treeWidget.topLevelItem(0).setText(0, _translate("MainWindow", "Text"))
self.treeWidget.topLevelItem(0).child(0).setText(0, _translate("MainWindow", "Sub Text"))
self.treeWidget.setSortingEnabled(__sortingEnabled)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Here is code and the image. Please let me know what changes should i make in the code to achieve my objective. Thanks in advance.
You have to establish a delegate in the second column that has as editor a QSpinBox:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
# ...
class IntegerDelegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = QtWidgets.QSpinBox(parent)
editor.setFrame(False)
editor.setMinimum(-2147483648)
editor.setMaximum(2147483647)
editor.setSizePolicy(
QtWidgets.QSizePolicy.Ignored, editor.sizePolicy().verticalPolicy()
)
return editor
class MainWindow(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
self.setupUi(self)
delegate = IntegerDelegate(self.treeWidget)
self.treeWidget.setItemDelegateForColumn(1, delegate)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
Update:
class DoubleDelegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index):
editor = QtWidgets.QDoubleSpinBox(parent)
editor.setFrame(False)
editor.setMinimum(-1.7976931348623157e+308)
editor.setMaximum(1.7976931348623157e+308)
editor.setSizePolicy(
QtWidgets.QSizePolicy.Ignored, editor.sizePolicy().verticalPolicy()
)
return editor

How to get selected item in table using pyqt?

I display data in a table from mysql database,
after that I want to when the rows in the table is clicked it will print the value in the line,that in print id existing data in the database. How do I make it to be like that?
Here's the source code:
from PyQt4 import QtCore, QtGui
import sys
import MySQLdb
from form.DBConnection import Connection
import MySQLdb as mdb
db = Connection()
myCursor = db.name().cursor()
"................................................
....................................."
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName(_fromUtf8("MainWindow"))
MainWindow.resize(655, 356)
self.centralwidget = QtGui.QWidget(MainWindow)
self.centralwidget.setObjectName(_fromUtf8("centralwidget"))
self.tbl_anggota = QtGui.QTableWidget(self.centralwidget)
self.tbl_anggota.setGeometry(QtCore.QRect(15, 40, 511, 192))
self.tbl_anggota.setObjectName(_fromUtf8("tbl_anggota"))
self.tbl_anggota.setColumnCount(3)
self.tbl_anggota.setRowCount(0)
item = QtGui.QTableWidgetItem()
self.tbl_anggota.setHorizontalHeaderItem(0, item)
item = QtGui.QTableWidgetItem()
self.tbl_anggota.setHorizontalHeaderItem(1, item)
item = QtGui.QTableWidgetItem()
self.tbl_anggota.setHorizontalHeaderItem(2, item)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtGui.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 655, 21))
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)
self.table(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None))
item = self.tbl_anggota.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "NIM", None))
item = self.tbl_anggota.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "NAMA", None))
item = self.tbl_anggota.horizontalHeaderItem(2)
def table(self, MainWindow):
myCursor.execute("SELECT * FROM anggota")
jum_baris= myCursor.fetchall()
self.tbl_anggota.setRowCount(len(jum_baris))
self.tbl_anggota.setColumnCount(3)
for i in range (len(jum_baris)):
for j in range (3):
item = Qt.QTableWidgetItem('%s' % (jum_baris[i][j + 1]))
self.tbl_anggota.setItem(i, j, item)
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
MainWindow = QtGui.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
This line of code will select the current row
r = self.tbl_anggota.currentRow()
If you know your columns (ie. it's not dynamic) you can then pull the value of each of your cells by doing this:
field1 = self.tbl_anggota.item(r,0).text()
field2 = self.tbl_anggota.item(r,1).text()
In this case, the 0 and the 1 in the item call are your columns, in a 0 indexed array. Remember that hidden columns still count.
To do this automatically when a row is clicked, you'll want to use the signal itemClicked

Categories