I am using PyQt5 and i have a qtablewidget where i list the items from the database. Every item has an enter time and exit time but all the exit time is empty at first. I am using a logic like if exit time is empty show a button, but if not show the exit time. I can change the exit time with the button and i want the button to disappear after the change but button is not disappearing until i restart the program.
I have another button for editing the rows and i used it to understand the stuation and plug it to a function to change the exitTime to empty. if i click the edit exitTime changes to the empty and exit button comes back but i cant make the exit button go by clicking the exit
def loadData(self):
databse.connection
result = mcursor.fetchall()
row=0
self.ui.carList.setRowCount(len(result))
for r in result:
self.btn_sell = QtWidgets.QPushButton('Çıkış')
self.btn_sell.clicked.connect(self.handleButtonClicked)
self.btnEdit = QtWidgets.QPushButton('Düzenle')
self.btnEdit.clicked.connect(self.updateDialog)
self.ui.carList.setItem(row, 0, QtWidgets.QTableWidgetItem(r[1]))
self.ui.carList.setItem(row, 1, QtWidgets.QTableWidgetItem(r[2]))
self.ui.carList.setItem(row, 2, QtWidgets.QTableWidgetItem(r[3]))
self.ui.carList.setItem(row, 3, QtWidgets.QTableWidgetItem(r[5].strftime('%H:%M:%S %Y-%m-%d')))
if r[6].strftime('%Y-%m-%d %H:%M:%S') == "1000-01-01 00:00:00":
self.ui.carList.setCellWidget(row, 4, self.btn_sell)
else:
self.ui.carList.setItem(row, 4, QtWidgets.QTableWidgetItem(r[6].strftime('%H:%M:%S %Y-%m-%d')))
self.ui.carList.setCellWidget(row, 5, self.btnEdit)
row += 1
minimal reproducible example:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QFileDialog, QMainWindow, QStyleFactory, QTabWidget, QInputDialog
from stack import Ui_MainWindow
from PyQt5.QtGui import QPixmap, QImage
import os
from datetime import datetime
def dbFunc(): # for creating the list for the first time
db = [["ahmet", "yıldırım", "KS67AEA", "23:09:39 2021-04-09", "23:09:39 2021-04-09"],
["mahmut", "celik", "TR67AKH", "23:09:39 2021-04-09", "1000-01-01 00:00:00"],
["mehmet", "gezen", "YU67OKY", "23:09:39 2021-04-09", "23:09:39 2021-04-09"],
["hakan", "duz", "PT67LDK", "23:09:39 2021-04-09", "1000-01-01 00:00:00"],
["ayse", "kavruk", "EO67KHL", "23:09:39 2021-04-09", "1000-01-01 00:00:00"]]
#print(db)
f = open("dbText.txt", "a")
for item in db:
for i in item:
f.write(i)
f.write(",")
f.write("\n")
f.close()
def toList():#read list
f = open("dbText.txt", "r")
dbList = f.read()
dbList = dbList.split("\n")
list = []
for i in dbList:
list.append(i.split(",")[:-1])
list.pop(-1)
f.close()
return list
def refreshFile(db):
os.remove('./dbText.txt')
f = open("dbText.txt", "a")
for item in db:
for i in item:
f.write(i)
f.write(",")
f.write("\n")
f.close()
class stapp(QMainWindow):
def __init__(self):
super(stapp, self).__init__()
self.ui = Ui_MainWindow()
self.ui.setupUi(self)
self.loadData()
#dbFunc() # for creating the list for the first time
dbList = toList()
def loadData(self):
result = self.dbList
row=0
self.ui.tableWidget.setRowCount(len(result))
for r in result:
self.btn_sell = QtWidgets.QPushButton('Çıkış')
self.btn_sell.clicked.connect(self.exit)
self.btnEdit = QtWidgets.QPushButton('Düzenle')
self.btnEdit.clicked.connect(self.updateDialog)
self.ui.tableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem(r[0]))
self.ui.tableWidget.setItem(row, 1, QtWidgets.QTableWidgetItem(r[1]))
self.ui.tableWidget.setItem(row, 2, QtWidgets.QTableWidgetItem(r[2]))
self.ui.tableWidget.setItem(row, 3, QtWidgets.QTableWidgetItem(r[3]))
if r[4] == "1000-01-01 00:00:00":
self.ui.tableWidget.setCellWidget(row, 4, self.btn_sell)
else:
self.ui.tableWidget.setItem(row, 4, QtWidgets.QTableWidgetItem(r[4]))
self.ui.tableWidget.setCellWidget(row, 5, self.btnEdit)
row += 1
def exit(self):
button = QtWidgets.qApp.focusWidget()
index = self.ui.tableWidget.indexAt(button.pos())
if index.isValid():
result = self.dbList
now = datetime.now()
time = now.strftime('%Y-%m-%d %H:%M:%S')
result[index.row()][4] = time
refreshFile(self.dbList)
self.loadData()
def updateDialog(self):
button = QtWidgets.qApp.focusWidget()
index = self.ui.tableWidget.indexAt(button.pos())
if index.isValid():
result = self.dbList
time = "1000-01-01 00:00:00"
result[index.row()][4]=time
self.loadData()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
app.setStyle(QStyleFactory.create('GTK+'))
win = stapp()
win.show()
sys.exit(app.exec_())
Uİ:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(424, 279)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(10, 10, 401, 221))
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(6)
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)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(4, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(5, item)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 424, 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", "name"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "surname"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "enterTime"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("MainWindow", "exitTime"))
item = self.tableWidget.horizontalHeaderItem(4)
item.setText(_translate("MainWindow", "exit"))
item = self.tableWidget.horizontalHeaderItem(5)
item.setText(_translate("MainWindow", "edit"))
Related
I want to create the basic look of my GUI with Qt-Designer, and add the functions via coding afterwards. Maybe there is already the Problem, but let's go on further.
My GUI that i created via Qt desinger consists of a 4x4 Table and a button.
When the Button is pressed, i want to write something in the cells of the Table.
(Sure, this in particular would be possible without using Qt desinger. But for the future there iwant to creat some more difficult GUIs. And therefore the Qt designer does save quite some time for a newbie like me :) )
The GUI code is:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(686, 539)
self.widget = QtWidgets.QWidget(Form)
self.widget.setGeometry(QtCore.QRect(10, 60, 258, 223))
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidget = QtWidgets.QTableWidget(self.widget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(4)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(3, item)
self.verticalLayout.addWidget(self.tableWidget)
self.pushButton = QtWidgets.QPushButton(self.widget)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
self.pushButton.clicked.connect(say_hello)
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
item = self.tableWidget.verticalHeaderItem(0)
item.setText(_translate("Form", "1"))
item = self.tableWidget.verticalHeaderItem(1)
item.setText(_translate("Form", "2"))
item = self.tableWidget.verticalHeaderItem(2)
item.setText(_translate("Form", "3"))
item = self.tableWidget.verticalHeaderItem(3)
item.setText(_translate("Form", "4"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("Form", "A"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("Form", "B"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("Form", "C"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("Form", "D"))
testitem=QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(1, 0, testitem)
self.pushButton.setText(_translate("Form", "PushButton"))
self.pushButton.clicked.connect(say_hello(testitem))
def say_hello(testitem):
print("Hello you!")
testitem.setText("Hi")
the GUI gets called from another file like that:
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtWidgets import QApplication
import sys
import GUI_PyQtn
class ExampleApp(QtWidgets.QWidget, GUI_PyQtn.Ui_Form):
def __init__(self, parent=None):
super(ExampleApp, self).__init__(parent)
self.setupUi(self)
def main():
app = QApplication(sys.argv)
form = ExampleApp()
form.show()
app.exec_()
if __name__ == '__main__':
main()
My thoughts on my approach were, creating the Cell object and pass it to the function "say_hello". If the function would be inside the Ui_Form Class, it acutally called it not even once.
I believe you can get what you're looking for with the following tweaks.
Declare testitem with self in class Ui_Form
Declare say_hello in class Ui_Form
Pass testitem in say_hello by lambda
No use click.connect() in retranslateUi
that's it
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName("Form")
Form.resize(686, 539)
self.widget = QtWidgets.QWidget(Form)
self.widget.setGeometry(QtCore.QRect(10, 60, 258, 223))
self.widget.setObjectName("widget")
self.verticalLayout = QtWidgets.QVBoxLayout(self.widget)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.tableWidget = QtWidgets.QTableWidget(self.widget)
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(4)
self.tableWidget.setRowCount(4)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(3, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(3, item)
self.verticalLayout.addWidget(self.tableWidget)
self.pushButton = QtWidgets.QPushButton(self.widget)
self.pushButton.setObjectName("pushButton")
self.verticalLayout.addWidget(self.pushButton)
# declare testitem with self ih here
self.testitem=QtWidgets.QTableWidgetItem()
# pass testitem in say_hello
self.pushButton.clicked.connect(lambda: self.say_hello(self.testitem))
self.retranslateUi(Form)
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
_translate = QtCore.QCoreApplication.translate
Form.setWindowTitle(_translate("Form", "Form"))
item = self.tableWidget.verticalHeaderItem(0)
item.setText(_translate("Form", "1"))
item = self.tableWidget.verticalHeaderItem(1)
item.setText(_translate("Form", "2"))
item = self.tableWidget.verticalHeaderItem(2)
item.setText(_translate("Form", "3"))
item = self.tableWidget.verticalHeaderItem(3)
item.setText(_translate("Form", "4"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("Form", "A"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("Form", "B"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("Form", "C"))
item = self.tableWidget.horizontalHeaderItem(3)
item.setText(_translate("Form", "D"))
#self.testitem=QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(1, 0, self.testitem)
#self.pushButton.setText(_translate("Form", "PushButton"))
#self.pushButton.clicked.connect(self.say_hello(testitem))
# say_hello in class
def say_hello(self, testitem):
testitem.setText('Hi')
How to filter items along with QCheckbox from QLineEdit and without Case-insensitive .
If i am using below code working but unable to get QCheckboxes along with items. Able to see items only not check boxes.
Below is my example Code:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_Dialog(object):
def setupUi(self, Dialog):
Dialog.setObjectName("Dialog")
Dialog.resize(333, 373)
self.gridLayout = QtWidgets.QGridLayout(Dialog)
self.gridLayout.setObjectName("gridLayout")
self.searchLineEdit = QtWidgets.QLineEdit(Dialog)
self.searchLineEdit.setObjectName("searchLineEdit")
self.gridLayout.addWidget(self.searchLineEdit, 0, 1, 1, 1)
self.label = QtWidgets.QLabel(Dialog)
self.label.setObjectName("label")
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
self.listWidget = QtWidgets.QListWidget(Dialog)
self.listWidget.setObjectName("listWidget")
self.gridLayout.addWidget(self.listWidget, 1, 0, 1, 2)
self.retranslateUi(Dialog)
QtCore.QMetaObject.connectSlotsByName(Dialog)
fruit_list = ["Apples", "pears", "oranges", "grapefruits", "strawberries"]
self.fruit_list = dict.fromkeys(fruit_list, 0)
for i in self.fruit_list:
item = QtWidgets.QListWidgetItem(i)
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Unchecked)
self.listWidget.addItem(item)
self.searchLineEdit.textChanged.connect(self.filter_items)
def retranslateUi(self, Dialog):
_translate = QtCore.QCoreApplication.translate
Dialog.setWindowTitle(_translate("Dialog", "Dialog"))
self.label.setText(_translate("Dialog", "Search"))
def filter_items(self, text):
self.listWidget.clear()
for item in self.fruit_list:
if text in item:
QtWidgets.QListWidgetItem(item, self.listWidget)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
Dialog = QtWidgets.QDialog()
ui = Ui_Dialog()
ui.setupUi(Dialog)
Dialog.show()
sys.exit(app.exec_())
You don't need to delete items: just hide them
def filter_items(self, text):
for i in range(self.listWidget.count()):
item = self.listWidget.item(i)
item.setHidden(text not in item.text())
I'm new to PyQt5 and I'm using Qtdesigner to develop an interface.
I am controlling the number of rows of a Table Widget from the spinbox. However, when changing the number of rows I need to keep the check option for column a.
I managed to change the number of rows according to valueChanged in the spinbox, but the loop I created to create the check regardless of the number of rows did not work.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(519, 468)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.spinBox = QtWidgets.QSpinBox(self.centralwidget)
self.spinBox.setGeometry(QtCore.QRect(80, 131, 41, 31))
self.spinBox.setProperty("value", 2)
self.spinBox.setObjectName("spinBox")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(160, 80, 341, 101))
self.tableWidget.setObjectName("tableWidget")
self.tableWidget.setColumnCount(2)
self.tableWidget.setRowCount(2)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setVerticalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
item.setFlags(QtCore.Qt.ItemIsUserCheckable|QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Checked)
self.tableWidget.setItem(0, 0, item)
item = QtWidgets.QTableWidgetItem()
item.setFlags(QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Checked)
self.tableWidget.setItem(1, 0, item)
item = QtWidgets.QTableWidgetItem()
self.tableWidget.setItem(1, 1, item)
self.tableWidget.verticalHeader().setVisible(False)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 519, 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)
self.spinBox.valueChanged['int'].connect(self.tableWidget.setRowCount)
for i in range(self.tableWidget.rowCount()):
item = QtWidgets.QTableWidgetItem()
item.setFlags(QtCore.Qt.ItemIsEnabled)
item.setCheckState(QtCore.Qt.Checked)
self.tableWidget.setItem(i, 0, item)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
item = self.tableWidget.verticalHeaderItem(0)
item.setText(_translate("MainWindow", "d"))
item = self.tableWidget.verticalHeaderItem(1)
item.setText(_translate("MainWindow", "e"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "a"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "c"))
__sortingEnabled = self.tableWidget.isSortingEnabled()
self.tableWidget.setSortingEnabled(False)
self.tableWidget.setSortingEnabled(__sortingEnabled)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
item = self.tableWidget.verticalHeaderItem(0)
item.setText(_translate("MainWindow", "d"))
item = self.tableWidget.verticalHeaderItem(1)
item.setText(_translate("MainWindow", "e"))
item = self.tableWidget.horizontalHeaderItem(0)
item.setText(_translate("MainWindow", "a"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "c"))
__sortingEnabled = self.tableWidget.isSortingEnabled()
self.tableWidget.setSortingEnabled(False)
self.tableWidget.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_())
First of all, it seems like you're editing the output of a pyuic generated file, or you're trying to mimic its behavior. In any case, this is something that should never be done.
Those files are meant to be left as they are, and you should only use them as modules; to know how to correctly do this, read more about using Designer. If you're trying to mimic their behavior, well, you shouldn't: the way pyuic files are treated is only considered as an "interpretation layer" in order to create the GUI objects and make them accessible from python. If you're building the GUI from code, just subclass the QWidget you want to use (QWidget, QDialog or QMainWindow, usually).
Now, the problem is that whenever setRowCount() is called...:
[it] Sets the number of rows in this table's model to rows. If this is less than rowCount(), the data in the unwanted rows is discarded.
This obviously means that, if you're removing rows, you're losing all items in that row (including the fact that they are checkable at all).
To correctly update the contents and add checkable items, you'll need to do that in a specific method that dynamically removes or adds items.
In the next example I'll show how to correctly implement this (and in an easier, clearer way):
from PyQt5 import QtCore, QtWidgets
class MainWindow(QtWidgets.QMainWindow):
def __init__(self):
super().__init__()
central = QtWidgets.QWidget()
self.setCentralWidget(central)
layout = QtWidgets.QHBoxLayout(central)
self.spin = QtWidgets.QSpinBox()
layout.addWidget(self.spin)
self.table = QtWidgets.QTableWidget(2, 2)
layout.addWidget(self.table)
self.table.verticalHeader().setVisible(False)
for col, label in enumerate(('a', 'c')):
header = QtWidgets.QTableWidgetItem(label)
self.table.setHorizontalHeaderItem(col, header)
if col:
continue
for row in range(self.table.rowCount()):
item = QtWidgets.QTableWidgetItem()
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Checked)
self.table.setItem(row, col, item)
self.spin.setValue(self.table.rowCount())
self.spin.valueChanged.connect(self.setRowCount)
def setRowCount(self, count):
if count == self.table.rowCount():
return
# if there are too many rows, remove them
while self.table.rowCount() > count:
self.table.removeRow(self.table.rowCount() - 1)
# if rows are going to be added, create checkable items for them
while self.table.rowCount() < count:
row = self.table.rowCount()
self.table.insertRow(row)
item = QtWidgets.QTableWidgetItem()
item.setFlags(item.flags() | QtCore.Qt.ItemIsUserCheckable)
item.setCheckState(QtCore.Qt.Checked)
self.table.setItem(row, 0, item)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
test = MainWindow()
test.show()
sys.exit(app.exec_())
As a side note, a couple of considerations:
a layout manager should always be used for widgets, otherwise the contents might become invisible or won't adjust their position;
you're defining retranslateUi twice; I suppose that's something that remained from editing the pyuic file, but, in any case, redifining a function with the same name results in overwriting it (unless each of them have an unique decorator)
I'm setting a filtering tool in Python 3.7 and I'm using pyqt5. I've created a qtablewidget to store the filters and their complementaries chosen by the user. I'd like to allow the user to combine filters over a data so I added grouped checkboxes in each row to select wanted filters.
Which commands should I use to loop over my qtable to get which checkbox is selected please?
def bindApply(self):
checked_list = []
for i in range(self.tableWidget.rowCount()):
#print(self.tableWidget.rowCount())
if self.tableWidget.item(i, 1).checkState() == QtCore.Qt.Checked:
checked_list.append([i,1])
elif self.tableWidget.item(i, 2).checkState() == QtCore.Qt.Checked:
checked_list.append([i,2])
else:
pass
return(checked_list)
I expect a list containing the indexes of selected rows and columns but my function returns nothing.
Here is a reproducible example:
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(550, 350)
MainWindow.setMinimumSize(QtCore.QSize(550, 350))
MainWindow.setMaximumSize(QtCore.QSize(550, 350))
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tableWidget = QtWidgets.QTableWidget(self.centralwidget)
self.tableWidget.setGeometry(QtCore.QRect(20, 20, 500, 200))
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)
self.pushButton_Save = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_Save.setGeometry(QtCore.QRect(120, 250, 100, 50))
self.pushButton_Save.setMinimumSize(QtCore.QSize(100, 50))
self.pushButton_Save.setMaximumSize(QtCore.QSize(100, 50))
self.pushButton_Save.setObjectName("pushButton_Save")
self.pushButton_Apply = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_Apply.setGeometry(QtCore.QRect(260, 250, 100, 50))
self.pushButton_Apply.setMinimumSize(QtCore.QSize(100, 50))
self.pushButton_Apply.setMaximumSize(QtCore.QSize(100, 50))
self.pushButton_Apply.setObjectName("pushButton_Apply")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 550, 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", "Name"))
item = self.tableWidget.horizontalHeaderItem(1)
item.setText(_translate("MainWindow", "Filter"))
item = self.tableWidget.horizontalHeaderItem(2)
item.setText(_translate("MainWindow", "complementary"))
self.pushButton_Save.setText(_translate("MainWindow", "Save"))
self.pushButton_Apply.setText(_translate("MainWindow", "Apply"))
#============================ BINDING ===============================
self.pushButton_Save.clicked.connect(self.bindSave)
self.pushButton_Apply.clicked.connect(self.bindApply)
def bindSave(self):
numRows = self.tableWidget.rowCount()
self.tableWidget.insertRow(numRows)
groupButton = QtWidgets.QButtonGroup(self.tableWidget)
groupButton.setExclusive(True)
it1 = QtWidgets.QTableWidgetItem("filter "+str(numRows))
self.tableWidget.setItem(numRows, 0, it1)
ch_bx1 = QtWidgets.QCheckBox()
groupButton.addButton(ch_bx1)
self.tableWidget.setCellWidget(numRows, 1, ch_bx1)
ch_bx2 = QtWidgets.QCheckBox()
groupButton.addButton(ch_bx2)
self.tableWidget.setCellWidget(numRows, 2, ch_bx2)
def bindApply(self):
checked_list = []
for i in range(self.tableWidget.rowCount()):
#print(self.tableWidget.rowCount())
if self.tableWidget.item(i, 1).checkState() == QtCore.Qt.Checked:
checked_list.append([i,1])
elif self.tableWidget.item(i, 2).checkState() == QtCore.Qt.Checked:
checked_list.append([i,2])
else:
pass
print(checked_list)
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()
You should check the state of the check boxes assigned to the cells, not the state of the item associated with the cell, i.e.
def bindApply(self):
checked_list = []
for i in range(self.tableWidget.rowCount()):
#print(self.tableWidget.rowCount())
if self.tableWidget.cellWidget(i, 1).isChecked():
checked_list.append([i,1])
elif self.tableWidget.cellWidget(i, 2).isChecked():
checked_list.append([i,2])
else:
pass
print(checked_list)
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
Final
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_())
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:
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.