How to get selected item in table using pyqt? - python

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

Related

How to select a random row from a CSV file on pyqt5 UI

How do I select a random row from a CSV file and print the result on the user interface using pyqt5?
On a csv file there is a column with random unique numbers from 1 to 2531. I've wanted to do a randbetween which is a function from excel to generate a random number and select that random number and vlookup the succeeding rows.
The function loadCsv on mycode is what I use to print the content of the csv file, but I've only wanted to select atleast 1 row using that random number
This is my code
import random
import csv
import pandas as pd
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(1200, 850)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tableView = QtWidgets.QTableView(self.centralwidget)
self.tableView.setGeometry(QtCore.QRect(15, 21, 1170, 700))
self.tableView.setObjectName("tableView")
self.tableView.horizontalHeader().setStretchLastSection(True)
self.pushButton = QtWidgets.QPushButton(self.centralwidget)
self.pushButton.setGeometry(QtCore.QRect(370, 740, 140, 80))
self.pushButton.setObjectName("SELECT WINNER")
self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
self.pushButton_2.setGeometry(QtCore.QRect(650, 740, 140, 80))
self.pushButton_2.setObjectName("GENERATE CSV")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.pushButton.clicked.connect(self.loadCsv)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
self.model = QtGui.QStandardItemModel(MainWindow)
self.tableView.setModel(self.model)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.pushButton.setText(_translate("MainWindow", "SELECT WINNER"))
self.pushButton_2.setText(_translate("MainWindow", "GENERATE CSV"))
def loadCsv(self):
fileName = 'raffle.csv'
with open(fileName, "r") as fileInput:
for row in csv.reader(fileInput):
items = [
QtGui.QStandardItem(field)
for field in row
]
self.model.appendRow(items)
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_())
Thanks

Add qcheckbox in every row of qtablewidget

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)

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_())

Using psycopg2 and Qthreads together(or just postgresql and qthreads) and updating GUI

The orderbook in DB always shows the right orderbook, i just want to continually update it in a GUI. I've been trying to get this to work but when i try to run a cur statement the app just crashes. I suspect i need some help to not have to clear the tableelement each time too, but only update items that have changed(i'm assuming this is a smart thing but im not sure). If i have to use Qt's postgresql lib i will, but then you have to help me how to get that running :)
from PyQt5 import QtCore, QtGui, QtWidgets
from PyQt5.QtCore import pyqtSignal, QThread
import psycopg2
import sys
import time
conn = psycopg2.connect("dbname=myDb user=kris")
cur = conn.cursor()
class Ui_MainWindow(QThread):
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(50, 50, 711, 481))
self.tableWidget.setRowCount(3)
self.tableWidget.setColumnCount(4)
self.tableWidget.setHorizontalHeaderLabels(['Sum', 'Total', 'Size', 'Bid'])
self.tableWidget.setObjectName("tableWidget")
self.btnBuy = QtWidgets.QPushButton(self.centralwidget)
self.btnBuy.setGeometry(QtCore.QRect(50, 10, 91, 33))
self.btnBuy.setObjectName("btnBuy")
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 800, 29))
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.btnBuy.setText(_translate("MainWindow", "BUY"))
class MainUIClass(QtWidgets.QMainWindow, Ui_MainWindow):
def __init__(self, parent=None):
super().__init__()
self.setupUi(self)
self.threadclass = ThreadClass()
self.threadclass.start()
self.threadclass.updateTable.connect(self.updateTable)
def updateTable(self, val):
print(val)
if 'setRowCount' in val:
self.tableWidget.setRowCount(val['setRowCount'])
elif 'insertRow' in val:
self.tableWidget.insertRow(val['insertRow'])
elif 'setItem' in val:
rowNum = val['setItem'][0]
colNum = val['setItem'][1]
data = val['setItem'][2]
self.tableWidget.setItem(rowNum, colNum+2, QtWidgets.QTableWidgetItem(str(data)))
class ThreadClass(QtCore.QThread):
updateTable = pyqtSignal(dict)
def __init__(self, parent=None):
super().__init__()
def run(self):
cur.execute("select quantity, rate from orderbook where type = %s and market = %s order by rate asc limit 10;", (0, "BTC-ADA"))
orderbook = cur.fetchall()
conn.commit()
for rowNum, rowData in enumerate(orderbook):
self.updateTable.emit({"insertRow": 0})
for colNum, data in enumerate(rowData):
self.updateTable.emit({"setItem": [rowNum, colNum, data]})
if __name__ == "__main__":
a = QtWidgets.QApplication(sys.argv)
app = MainUIClass()
app.show()
#a.exec_()
cur.close()
conn.close()
sys.exit(a.exec_())
You are closing the database connection before Qt's main loop is started, move all Postgres related stuff into the thread.
class ThreadClass(QtCore.QThread):
updateTable = pyqtSignal(dict)
def __init__(self, parent=None):
super().__init__()
def run(self):
conn = psycopg2.connect("dbname=XXX user=YYYY password=ZZZ host=localhost port=5555")
cur = conn.cursor()
cur.execute("select * from events")
orderbook = cur.fetchall()
for rowNum, rowData in enumerate(orderbook):
self.updateTable.emit({"insertRow": 0})
for colNum, data in enumerate(rowData):
self.updateTable.emit({"setItem": [rowNum, colNum, data]})
cur.close()
conn.close()

QTableWidget: signal to detect start of cell edit

I have a PyQt5 QTableWidget with two connected signals. One signal is meant to fire and print text to the screen when the user starts editing a cell in the table; the other is meant to fire and print text when the user finishes editing.
The latter works by connecting a function to the cellChanged signal; however, the cellActivated signal doesn't fire when the user starts editing a cell in the table.
To be clear: I want a catch-all signal for any time the cell editing starts (i.e. when the blinking cursor appears in a table cell indicating the user can now type in the cell). So connecting to the doubleClick signal will not do the trick. Although, I would settle for just having it fire when the user begins editing by pressing the enter key.
Here is my code:
from PyQt5 import QtCore, QtWidgets
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(790, 472)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.tbwMain = QtWidgets.QTabWidget(self.centralwidget)
self.tbwMain.setGeometry(QtCore.QRect(0, 0, 801, 451))
self.tbwMain.setObjectName("tbwMain")
self.tabBoxes = QtWidgets.QWidget()
self.tabBoxes.setObjectName("tabBoxes")
self.horizontalLayoutWidget = QtWidgets.QWidget(self.tabBoxes)
self.horizontalLayoutWidget.setGeometry(QtCore.QRect(0, 0, 791, 421))
self.horizontalLayoutWidget.setObjectName("horizontalLayoutWidget")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.horizontalLayoutWidget)
self.horizontalLayout.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout.setObjectName("horizontalLayout")
spacerItem = QtWidgets.QSpacerItem(220, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.horizontalLayout.addItem(spacerItem)
self.tblBoxes = QtWidgets.QTableWidget(self.horizontalLayoutWidget)
self.tblBoxes.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOn)
self.tblBoxes.setVerticalScrollMode(QtWidgets.QAbstractItemView.ScrollPerPixel)
self.tblBoxes.setRowCount(1)
self.tblBoxes.setObjectName("tblBoxes")
self.tblBoxes.setColumnCount(3)
item = QtWidgets.QTableWidgetItem()
self.tblBoxes.setHorizontalHeaderItem(0, item)
item = QtWidgets.QTableWidgetItem()
self.tblBoxes.setHorizontalHeaderItem(1, item)
item = QtWidgets.QTableWidgetItem()
self.tblBoxes.setHorizontalHeaderItem(2, item)
item = QtWidgets.QTableWidgetItem()
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBoxes.setItem(0, 0, item)
item = QtWidgets.QTableWidgetItem()
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBoxes.setItem(0, 1, item)
item = QtWidgets.QTableWidgetItem()
item.setTextAlignment(QtCore.Qt.AlignCenter)
self.tblBoxes.setItem(0, 2, item)
self.tblBoxes.horizontalHeader().setStretchLastSection(True)
self.tblBoxes.verticalHeader().setVisible(False)
self.horizontalLayout.addWidget(self.tblBoxes)
spacerItem1 = QtWidgets.QSpacerItem(220, 40, QtWidgets.QSizePolicy.Minimum, QtWidgets.QSizePolicy.Expanding)
self.horizontalLayout.addItem(spacerItem1)
self.tbwMain.addTab(self.tabBoxes, "")
MainWindow.setCentralWidget(self.centralwidget)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
self.tbwMain.setCurrentIndex(0)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
# - - - - -
self.tblBoxes.cellActivated.connect(self.test1)
self.tblBoxes.cellChanged.connect(self.test2)
def test1(self):
print('Start cell edit!')
def test2(self):
print('End cell edit!')
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_())
To reiterate, I'm looking for a solution for printing the text "Start Cell Edit" whenever a cell of the table begins to be edited.
There are several different ways to do this. One way is to reimplement the edit method of the table-widget, and emit a custom signal:
class TableWidget(QtWidgets.QTableWidget):
cellEditingStarted = QtCore.pyqtSignal(int, int)
def edit(self, index, trigger, event):
result = super(TableWidget, self).edit(index, trigger, event)
if result:
self.cellEditingStarted.emit(index.row(), index.column())
return result
However, if you're using Qt Designer, it might be preferrable to avoid sub-classing the table-widget, and use an item-delegate instead:
class ItemDelegate(QtWidgets.QStyledItemDelegate):
cellEditingStarted = QtCore.pyqtSignal(int, int)
def createEditor(self, parent, option, index):
result = super(ItemDelegate, self).createEditor(parent, option, index)
if result:
self.cellEditingStarted.emit(index.row(), index.column())
return result
class Ui_MainWindow(object):
...
def retranslateUi(self, MainWindow):
self.delegate = ItemDelegate(MainWindow)
self.delegate.cellEditingStarted.connect(self.test1)
self.tblBoxes.setItemDelegate(self.delegate)
self.tblBoxes.cellActivated.connect(self.test2)

Categories