Refresh/Re-open Qdialog with QTableWidget inside - python

I have a program that is "divided" in 6 classes, the first class is the Main Window where I can choose where I'd like to go (I have 4 choices, a page to visualize all the data, one to modify and the other 2 to visualize data with filters), each of theese pages is a QDialog that contains a QTableWidget, this table is connected to a SQL Server database and shows data from a specific table (to be honest it shows data from 2 tables).
My problem is:
In the 2 class ("modificaviaggi") I connected some signals to some action, first of all I connected the itemChanged signal to a method that stores the items written by the user and saves them in the SQL DB, the signal signal I used is the clicked signal, I connected this signal to a method that verifies if the cell clicked it's the 8 or 9, in case it's 8 or 9 it shows another QDialog (class "articoli") where the user can insert some data regarding weight of every product, this weight data are stored in a second table in the SQL Server DB, I use this table to get the weight for every product when I show my table.
So I get all the data from the table SQL "Viaggi" and then I verify if there are some values in the SQL table "Pesi" for each row of the table "Viaggi" using the row ID.
Now the complicated part is that when the user click the columns 8 or 9 it shows another Qdialog, I show this Qdialog everytime the user clicks the columns 8 or 9, then the user can write data on the table and those data will be stored in the table "Pesi", thanks to the variable "lastID" declared on the "modificaviggi" class I know for which row the user clicked the columns 8 or 9, thanks to that I store the values in the SQL table and for each value I have their row ID, now that the situation is more clear the real question is: How can "Re-load" the QTableWidget "tabella_registrazioni" inside the class "modificaviaggi" everytime the user clicks the QPushButton "get_back_button"? Because in the class "articoli" the user modifies/adds values for each row in the QTableWidget "tabella_registrazioni" but I can't reload the data inside here's my code :
c = conn.cursor()
d = conndue.cursor()
class Ui(QtWidgets.QMainWindow):
def __init__(self):
super(Ui, self).__init__() # chiamare le inherited classi con metodo __init__
uic.loadUi('pagina_scelta.ui', self) # caricare file.ui
self.show() # mostrarlo
bottonefinestramodifica = self.findChild(QtWidgets.QPushButton, 'bottone_modifica')
bottonefinestramodifica.clicked.connect(self.finestramodifica)
def finestramodifica(self):
self.finestramodifica = modificaviaggi()
self.finestramodifica.show()
class MyDelegate(QStyledItemDelegate):
def createEditor(self, parent, option, index):
return
class modificaviaggi(QtWidgets.QDialog):
lastid = [0]
recall = [2]
def finestraarticoli(self):
self.finestraarticoli = articoli()
self.finestraarticoli.show()
def chiusura(self):
self.accept()
def __init__(self):
super(modificaviaggi, self).__init__()
uic.loadUi('modifica_reg.ui', self)
bottonetorna = self.bottone_torna
bottonetorna.clicked.connect(self.chiusura)
self.reloading()
self.datitabella()
def reloading(self):
if 1 == 1:
if self.recall[0] == 1:
self.datitabella()
self.recall[0] == 2
def datitabella(self):
delegate = MyDelegate(self)
tablerow = 0
conteggio = c.execute('SELECT COUNT(ID) FROM Viaggi').fetchone()[0]
print(conteggio)
customers = [" "]
self.tabella_registrazioni.blockSignals(True)
self.customers_combo(customers)
self.tabella_registrazioni.setRowCount(conteggio)
for row in c.execute("SELECT * FROM Viaggi "):
rigavalore = 0
self.tabella_registrazioni.setRowCount(conteggio)
for r in range(0, 19):
self.tabella_registrazioni.setItem(tablerow, rigavalore, QtWidgets.QTableWidgetItem(str(row[rigavalore])))
rigavalore+= 1
tablerow+= 1
self.combocreation(customers)
self.combocreation(customers)
self.tabella_registrazioni.blockSignals(False)
self.tabella_registrazioni.itemChanged.connect(self.changeIcon)
self.tabella_registrazioni.setItemDelegateForColumn(0, delegate)
self.tabella_registrazioni.clicked.connect(self.pressed)
self.combo_customers.activated.connect(self.customer_combo_selection)
righe = self.tabella_registrazioni.rowCount()
tablerow1= 0
for i in range(0, righe):
idrow = self.tabella_registrazioni.item(i, 0).text()
netweight = c.execute("SELECT SUM(Peso_netto) FROM Pesi WHERE ID_registrazione = ?", idrow)
if netweight != None or not netweight.isspace():
netweight = float(str(netweight.fetchone()[0]))
else:
print("Nessun peso")
grossweight = c.execute("SELECT SUM(Peso_lordo) FROM Pesi WHERE ID_registrazione = ?", idrow)
if grossweight != None or not grossweight.isspace():
grossweight = float(str(grossweight.fetchone()[0]))
self.tabella_registrazioni.setItem(tablerow1, 8, QtWidgets.QTableWidgetItem(str(netweight)))
self.tabella_registrazioni.setItem(tablerow1, 9, QtWidgets.QTableWidgetItem(str(grossweight)))
tablerow1+= 1
def combocreation(self, customers):
self.combo_customers = QComboBox()
self.combo_customers.setEditable(True)
def customers_combo(self, customers):
for cu in d.execute("SELECT ANDESCRI FROM VALL_CONTI WHERE ANTIPCON = 'C' "):
customers.append(cu[0].strip())
def changeIcon(self, item):
row = item.row()
col = item.column()
zero = self.tabella_registrazioni.item(row, 0).text()
uno = self.tabella_registrazioni.item(row, 1).text()
custcode = self.tabella_registrazioni.item(row, 3).text()
custname = self.tabella_registrazioni.item(row, 4).text()
c.execute('UPDATE Viaggi SET Codice_cliente = ?, Ragione_sociale = ? WHERE ID = ?',
(custcode, custname, zero))
c.commit()
def pressed(self, item):
row = item.row()
col = item.column()
customers = [" "]
self.lastid[0] = self.tabella_registrazioni.item(row, 0).text()
if col == 8 or col == 9:
self.finestraarticoli()
self.customers_combo(customers)
self.combocreation(customers)
textcell = self.tabella_registrazioni.item(row, col).text()
self.combo_customers.setCurrentText(textcell)
self.combo_customers.activated.connect(self.customer_combo_selection)
if col == 3:
self.tabella_registrazioni.setCellWidget(row, 3, self.combo_customers)
def customer_combo_selection(self):
customer_name = self.combo_customers.currentText()
row = self.rrow
self.tabella_registrazioni.setItem(self.rrow, self.ccolumn, QtWidgets.QTableWidgetItem(str(customer_name)))
id = self.tabella_registrazioni.item(row, 0).text()
c.execute("UPDATE Viaggi SET Ragione_Sociale=? WHERE ID = ?", (customer_name, id))
c.commit()
class articoli(QtWidgets.QDialog):
def changevariable(self):
modificaviaggi.recall[0] = 1
self.accept()
def __init__(self):
super(articoli, self).__init__()
uic.loadUi('Inserimento_articoli.ui', self)
self.get_back_button.clicked.connect(self.changevariable)
self.tabellapesi()
def tabellapesi(self):
self.IDpressed = modificaviaggi.lastid
tablerow = 0
self.tabella_articoli.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.ResizeToContents)
self.conteggio = int(str(c.execute("SELECT COUNT(ID_registrazione) FROM Pesi WHERE ID_registrazione = ? ", self.IDpressed[0]).fetchone()[0]))
for row in c.execute("SELECT * FROM Pesi WHERE ID_registrazione = ? ORDER BY ID ", self.IDpressed[0]):
rigavalore = 0
self.tabella_articoli.setRowCount(self.conteggio)
for r in range(0, 6):
self.tabella_articoli.setItem(tablerow, rigavalore, QtWidgets.QTableWidgetItem(str(row[rigavalore])))
rigavalore+= 1
tablerow+= 1
def insert(self):
rows = self.tabella_articoli.rowCount()
tablerow = 0
for row in range (0, rows):
articlecode = self.tabella_articoli.item(tablerow, 1).text()
articledesc = self.tabella_articoli.item(tablerow, 2).text()
netweight = float(self.tabella_articoli.item(tablerow, 3).text())
grossweight = float(self.tabella_articoli.item(tablerow, 4).text())
price = float(self.tabella_articoli.item(tablerow, 5).text())
if self.tabella_articoli.item(tablerow, 0) == None:
IDweight = ""
else:
IDweight = int(self.tabella_articoli.item(tablerow, 0).text())
queryinsert = "INSERT INTO Pesi ( Codice_articolo, Descrizione_articolo, Peso_netto, Peso_lordo, ID_registrazione, Prezzo) VALUES (?,?,?,?,?,?)"
values = [articlecode, articledesc, netweight, grossweight, self.IDpressed[0], price]
queryupdate = "UPDATE Pesi SET Peso_lordo = ?, Prezzo = ?, Peso_netto = ? , Codice_articolo = ?, Descrizione_articolo = ? WHERE ID = ? "
valuesupdate = [grossweight, price, netweight, articlecode, articledesc, IDweight]
exist = str(c.execute("IF EXISTS (SELECT * FROM CARICO_VIAGGI..Pesi WHERE ID = ?) BEGIN SELECT 1 END ELSE BEGIN SELECT 2 END", (IDweight)).fetchone()[0])
if exist == "1":
c.execute(queryupdate, valuesupdate)
c.commit()
print(type(IDweight))
elif exist == "2":
c.execute(queryinsert, values)
c.commit()
else:
print("Impossibile salvare gli articoli, riprovare")
tablerow+= 1
self.tabella_articoli.clearContents()
tablerow = 0
self.conteggiox = int(str(c.execute("SELECT COUNT(ID_registrazione) FROM Pesi WHERE ID_registrazione = ? ", self.IDpressed[0]).fetchone()[0]))
for row in c.execute("SELECT * FROM Pesi WHERE ID_registrazione = ? ORDER BY ID", self.IDpressed[0]):
rigavalore = 0
self.tabella_articoli.setRowCount(self.conteggiox)
for r in range(0, 6):
self.tabella_articoli.setItem(tablerow, rigavalore, QtWidgets.QTableWidgetItem(str(row[rigavalore])))
rigavalore+= 1
tablerow+= 1
app = QtWidgets.QApplication(sys.argv)
window = Ui()
app.exec_()

One solution could be to set up signals that would update the table as the user makes changes so there would be no need to refresh at all.
For example:
Set up a signal in your dialog class that will be emitted whenever the user changes the data. Then in the original dialog with the table you want to update, connect to that signal after initializing the dialog.
here is a minimal example:
import sys
from PyQt5.QtCore import *
from PyQt5.QtGui import *
from PyQt5.QtWidgets import *
def populate_table(table):
for i in range(10):
table.insertRow(table.rowCount())
for j in range(2):
item = QTableWidgetItem(type=0)
item.setText(f"({i}, {j})")
table.setItem(i,j,item)
class Dialog2(QDialog):
tableInfoChanged = pyqtSignal([int, int, str])
def __init__(self,parent=None):
super().__init__(parent=parent)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.table = QTableWidget()
self.table.setColumnCount(2)
self.layout.addWidget(self.table)
populate_table(self.table)
self.table.cellChanged.connect(self.emitChangedInfo)
def emitChangedInfo(self, row, col):
text = self.table.item(row, col).text()
self.tableInfoChanged.emit(row, col, text)
class Dialog1(QDialog):
def __init__(self,parent=None):
super().__init__(parent=parent)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
self.table = QTableWidget()
self.table.setColumnCount(2)
self.button = QPushButton("Push to open dialog2")
self.layout.addWidget(self.table)
self.layout.addWidget(self.button)
populate_table(self.table)
self.button.clicked.connect(self.openDialog2)
def updateTable(self, row, col, text):
self.table.item(row,col).setText(text)
def openDialog2(self):
self.dialog2 = Dialog2()
self.dialog2.tableInfoChanged.connect(self.updateTable)
self.dialog2.exec()
app = QApplication(sys.argv)
window = Dialog1()
window.show()
sys.exit(app.exec_())
I have tested this code and should function as is.

Related

Having a problem displaying the correct value in the edit workorder QComboBox

I am trying to set the current value of the order_type_combo QComboBox 29: 'Complaint: Damage caused by sewer blockages' instead I'm getting a default value 2: 'Complaint: Sewerage Blockage'. These values are created in a table t_wo_workorders which uses another table wo_type as a dropdown.
Here is my code:
from PyQt5 import QtWidgets, QtGui
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QPushButton, QLineEdit, QVBoxLayout, QDateEdit, QComboBox, QStyleFactory, QTableView, QMessageBox, QSizePolicy, QTextEdit
from PyQt5.QtCore import Qt
from PyQt5.QtGui import QFont, QStandardItemModel, QStandardItem, QPalette
import psycopg2
import datetime
from PyQt5.QtCore import QDate
from PyQt5.QtWidgets import QDateEdit
from PyQt5.QtCore import QTimer
current_date = QDate.currentDate()
# Connect to the database and create a cursor object
conn = psycopg2.connect(
host="localhost",
database="mms",
user="postgres",
password="postgres"
)
cur = conn.cursor()
# Retrieve the last work order from the t_wo_workorders table
cur.execute("SELECT * FROM t_wo_workorders ORDER BY order_id DESC LIMIT 1")
work_order = cur.fetchone()
# Extract the values for each field in the work order
work_order_id = work_order[0]
defined = work_order[1]
org = work_order[2]
order_type = work_order[3]
scheduled = work_order[4]
status = work_order[5]
request = work_order[6]
address = work_order[7]
customer = work_order[8]
tel_no = work_order[9]
class EditWorkOrderForm(QWidget):
def populate_org_combo(self):
self.cur.execute("SELECT org_unit, id FROM org_units")
org_units = self.cur.fetchall()
for org_unit in org_units:
self.org_combo.addItem(str(org_unit[0]))
self.org_units_dict[org_unit[1]] = org_unit[0]
def populate_order_type_combo(self, order_type):
self.order_type = order_type
# Retrieve the wo_type records from the database
self.cur.execute("SELECT type_description_en, id FROM wo_type")
wo_type = self.cur.fetchall()
# Create a dictionary with the id values as keys and the type_description_en values as values
self.order_types_dict = {}
for id, type_description_en in wo_type:
self.order_types_dict[id] = type_description_en
self.order_type_combo.addItem(str(type_description_en))
# Check if the order_type value is present in the order_types_dict dictionary
if self.order_type not in self.order_types_dict:
print("Error: Invalid order type")
return
# Get the index of the order_type value in the order_types_dict keys and set the combo box's current index to that value
default_index = list(self.order_types_dict.keys()).index(self.order_type)
self.order_type_combo.setCurrentIndex(default_index)
def populate_status_combo(self):
self.cur.execute("SELECT status_descr_en, id FROM wo_status")
wo_status = self.cur.fetchall()
for status in wo_status:
self.status_combo.addItem(str(status[0]))
self.status_dict[status[1]] = status[0]
def __init__(self, conn, cur, order_id, defined, org, order_type, scheduled, status, request, address, customer, tel_no):
super().__init__()
self.cur = cur # Assign the cur parameter to the self.cur attribute
self.order_types_dict = {}
self.order_type_combo = QComboBox(self)
self.populate_order_type_combo(order_type)
print(order_type)
self.conn = conn
self.org_units_dict = {}
self.status_dict = {}
self.order_id = order_id
self.org_combo = QComboBox(self)
self.populate_org_combo()
if str(org) in self.org_units_dict:
org_value = self.org_units_dict[int(org)]
else:
org_value = ""
try:
org_value = self.org_units_dict[int(org)]
except KeyError:
pass
org_index = self.org_combo.findText(org_value)
order_type_value = [v for k, v in self.order_types_dict.items() if k == order_type]
if order_type_value:
order_type_value = order_type_value[0]
else:
order_type_value = ""
order_type_index = self.order_type_combo.findText(order_type_value)
self.order_type_combo.setCurrentIndex(order_type_index)
self.status_combo = QComboBox(self)
self.populate_status_combo()
conn = psycopg2.connect(
host="localhost",
database="mms",
user="postgres",
password="postgres"
)
self.cur.execute(
"SELECT * FROM t_wo_workorders WHERE order_id = %s",
(self.order_id,)
)
work_order = self.cur.fetchone()
self.defined_label = QLabel("Defined:")
self.defined_edit = QDateEdit()
self.defined_edit.setDate(defined)
self.org_label = QLabel("Org. Unit:")
self.org_combo.setGeometry(100, 100, 200, 25)
self.org_combo.setCurrentIndex(int(org))
self.org_combo.setCurrentIndex(org_index)
self.order_type_label = QLabel("Order Type:")
self.order_type_combo.setGeometry(100, 100, 200, 25)
self.order_type_combo.setCurrentIndex(int(order_type))
self.order_type_combo.setCurrentIndex(order_type_index)
self.scheduled_label = QLabel("Scheduled:")
self.scheduled_edit = QDateEdit()
self.scheduled_edit.setDate(scheduled)
self.status_label = QLabel("Status:")
self.status_combo = QComboBox()
self.order_type_combo.setCurrentIndex(int(status))
status_value = self.status_dict.get(org, "")
status_index = self.status_combo.findText(status_value)
self.request_label = QLabel("Request:")
self.request_edit = QLineEdit()
self.request_edit.setText(request)
self.address_label = QLabel("Address:")
self.address_edit = QLineEdit()
self.address_edit.setText(address)
self.customer_label = QLabel("Customer:")
self.customer_edit = QLineEdit()
self.customer_edit.setText(customer)
self.tel_no_label = QLabel("Tel. No:")
self.tel_no_edit = QLineEdit()
self.tel_no_edit.setText(tel_no)
self.request_gps_label = QLabel("Request GPS:")
layout = QVBoxLayout()
layout.addWidget(self.defined_label)
layout.addWidget(self.defined_edit)
layout.addWidget(self.org_label)
layout.addWidget(self.org_combo)
layout.addWidget(self.order_type_label)
layout.addWidget(self.order_type_combo)
layout.addWidget(self.scheduled_label)
layout.addWidget(self.scheduled_edit)
layout.addWidget(self.status_label)
layout.addWidget(self.status_combo)
layout.addWidget(self.request_label)
layout.addWidget(self.request_edit)
layout.addWidget(self.address_label)
layout.addWidget(self.address_edit)
layout.addWidget(self.customer_label)
layout.addWidget(self.customer_edit)
layout.addWidget(self.tel_no_label)
layout.addWidget(self.tel_no_edit)
layout.addWidget(self.request_gps_label)
self.setLayout(layout)
self.show()
def edit_work_order(self, work_order_id):
form = EditWorkOrderForm(work_order_id)
form.show()
def create_edit_work_order_form(work_order_id, defined, org, order_type, scheduled, status, request, address, customer, tel_no):
form = EditWorkOrderForm(conn, cur, work_order_id, defined, org, order_type, scheduled, status, request, address, customer, tel_no)
return form
app = QApplication(sys.argv)
edit_work_order_form = EditWorkOrderForm(conn, cur, work_order_id, defined, org, order_type, scheduled, status, request, address, customer, tel_no)
edit_work_order_form.show()
sys.exit(app.exec_())
and this is what it prints:
Error: Invalid order type
3
[Finished in 5.3s]

How to move items from one QTreeWidget to another QTreeWidget and keep track of information?

I have a GUI where user selects gas components from list and moves it to 'Chosen' and another button takes text from 'Chosen' that has columns: Gas Component, Molecular Weight, Mol%. The first two columns get information from a dictionary that i've created, and last column is user input.
When button is clicked and all values are filled in 'Chosen', it will ask user for a number, n = 1-6 , it will then take rows with n highest mol% in 'Chosen' and create n rows in Results and add Gas Component text with n highest mol% values, to first column in 'Results'
I am currently using dictionaries to keep track of information.
def calculategas(self):
#makes sure dictionaries are clear for any errors on rerunning button
self.sortedmol.clear()
self.componentDic1.clear()
self.componentDic2.clear()
self.componentDic3.clear()
self.mmDict.clear()
self.mfDict.clear()
self.mDict.clear()
self.massFracDict.clear()
self.molarmassDict.clear()
self.item_.clear()
self.lookup.clear()
root = self.chosen.invisibleRootItem()
child_count = root.childCount()
for i in range(child_count):
item = root.child(i)
#Takes text from self.chosen QTreeWidget (Top-right)
component = item.text(0)
molWeight = item.text(1)
componentMol = float(item.text(2))
#creates dictionary of items in self.chosen
self.componentDic1[component] = componentMol
self.componentDic2[molWeight] = componentMol
#Sorts dictionaries above from highest to lowest
self.sortedmol = dict(sorted(self.componentDic1.items(), key=operator.itemgetter(1),
reverse=True)) # Sorted component list - largest to smallest mol%
self.sortedmolar = dict(sorted(self.componentDic2.items(), key=operator.itemgetter(1),
reverse=True)) # Sorted molar mass list - largest to smallest mol%
# change values of self.sortedmol with keys of self.sortedmolar
self.lookup = {v:k for k, v in self.sortedmol.items()}
self.componentDic3 = {self.lookup[v]: float(k) for k, v in self.sortedmolar.items()}
##Copies so original doesn't change
self.mmDict = self.sortedmol.copy()
self.mfDict = self.mmDict.copy()
self.mDict = self.componentDic3.copy()
###Calculations
self.molarmassDict = {k: round(v * self.mmDict[k] / 100, 3) for k, v in self.mDict.items() if
k in self.mmDict}
summolmDict = round(sum(self.molarmassDict.values()), 3)
self.massFracDict = {k: round(self.molarmassDict[k] / summolmDict, 3) for k, v in self.molarmassDict.items()
if
k in self.molarmassDict}
componentNum, ok = QInputDialog.getText(None, 'Number of components', 'How many components do you wish to use?')
if (ok):
#Remove any items in result QTreeWidget
current_item = self.result.invisibleRootItem()
children = []
for child in range(current_item.childCount()):
children.append(current_item.child(child))
for child in children:
current_item.removeChild(child)
#Adds rows to self.result QTreeWidget
for i in range(int(componentNum)):
self.item_[i] = QtWidgets.QTreeWidgetItem(self.result)
self.item_[i].setFlags(
QtCore.Qt.ItemIsSelectable | QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsDragEnabled | QtCore.Qt.ItemIsUserCheckable | QtCore.Qt.ItemIsEnabled)
if len(self.sortedmol) > int(componentNum): # takes only # of components user wants
##Adds the number of components user inputs with highest mol% to self.result
root = self.result.invisibleRootItem()
child_count = root.childCount()
for i in range(child_count):
item = root.child(i)
item.setText(0, str(list(self.massFracDict)[i])) # update first column with dictionary keys
else:
###This section will change
root = self.result.invisibleRootItem()
child_count = root.childCount()
for i in range(child_count):
item = root.child(i)
item.setText(0, str(list(self.massFracDict)[i])) # update first column with dictionary keys
Currently everything works except that when there is a duplicate value in mol% or molecular weight it will tend to skip it.
Dictionary self.sortedmol:
Keys = Gas Component text
Values = mol% text
Dictionary self.sortedmolar:
Keys = Molecular Weight text
Values = mol% text
Problems:
If two components have same molecular weight, it will ignore it
If two components have same mol%, it will ignore it
Overall goal: Add rows with n highest mol% in 'Chosen' to 'Result and keep values for later calculations.
Question: Is there any way to fix this error, or use another way to get same desired results?
Step1:
Step2:
If you want to get the n rows where the mol% are the highest then you must use a QSortFilterProxyModel to sort, and another to filter.
from PyQt5 import QtCore, QtGui, QtWidgets
ListRole = QtCore.Qt.UserRole
VisibleRole = QtCore.Qt.UserRole + 1
class TopProxyModel(QtCore.QSortFilterProxyModel):
#property
def number(self):
if not hasattr(self, "_number"):
self._number = -1
return self._number
#number.setter
def number(self, number):
self._number = number
self.invalidateFilter()
def filterAcceptsRow(self, sourceRow, sourceParent):
if self.number < 0:
ix = self.sourceModel().index(sourceRow, 2)
self.sourceModel().setData(ix, False, VisibleRole)
return True
return sourceRow < self.number
class BlankDelegate(QtWidgets.QStyledItemDelegate):
def initStyleOption(self, option, index):
super().initStyleOption(option, index)
if not index.data(VisibleRole):
option.text = ""
def setModelData(self, editor, model, index):
sm = model
ix = index
while hasattr(sm, "sourceModel"):
ix = sm.mapToSource(ix)
sm = sm.sourceModel()
sm.setData(ix, editor.value(), QtCore.Qt.DisplayRole)
if not sm.data(ix, VisibleRole):
sm.setData(ix, True, VisibleRole)
class ReadOnlyDelegate(QtWidgets.QStyledItemDelegate):
def createEditor(self, parent, option, index):
return None
class Widget(QtWidgets.QWidget):
def __init__(self, parent=None):
super().__init__(parent)
datas = [
("IsonButane", 58.12, 13),
("IsonPentane", 75.12, 3),
("Methane", 16.04, 5),
("Nitrogen", 28.01, 5),
("Hexane", 86.17, 5),
("Hydrogen", 2.02, 13),
("Hydrogen Sulfide", 34.08, 2),
]
add_button = QtWidgets.QPushButton(">>>", clicked=self.add_row)
remove_button = QtWidgets.QPushButton("<<<", clicked=self.remove_row)
select_button = QtWidgets.QPushButton("Calculate", clicked=self.select)
sp = select_button.sizePolicy()
sp.setHorizontalPolicy(QtWidgets.QSizePolicy.Maximum)
select_button.setSizePolicy(sp)
self.listwidget = QtWidgets.QListWidget(
selectionMode=QtWidgets.QAbstractItemView.MultiSelection
)
for data in datas:
item = QtWidgets.QListWidgetItem(data[0])
item.setData(ListRole, data)
self.listwidget.addItem(item)
self.tree_widget = QtWidgets.QTreeWidget(
columnCount=3,
indentation=0,
selectionMode=QtWidgets.QAbstractItemView.MultiSelection,
)
for i, T in enumerate(
(ReadOnlyDelegate, ReadOnlyDelegate, BlankDelegate)
):
delegate = T(self.tree_widget)
self.tree_widget.setItemDelegateForColumn(2, delegate)
self.tree_widget.setHeaderLabels(
["Gas Component", "Molecular Weight", "Mol%"]
)
self.tree_view = QtWidgets.QTreeView(indentation=0)
proxy_sort = QtCore.QSortFilterProxyModel(self)
proxy_sort.setSourceModel(self.tree_widget.model())
proxy_sort.sort(2, QtCore.Qt.DescendingOrder)
self.proxy_top = TopProxyModel(self)
self.proxy_top.number = 0
self.proxy_top.setSourceModel(proxy_sort)
self.tree_view.setModel(self.proxy_top)
lay = QtWidgets.QGridLayout(self)
lay.addWidget(QtWidgets.QLabel("<b>Available Gases:</b>"), 0, 0)
lay.addWidget(self.listwidget)
vlay = QtWidgets.QVBoxLayout()
vlay.addStretch()
vlay.addWidget(add_button)
vlay.addWidget(remove_button)
vlay.addStretch()
lay.addLayout(vlay, 1, 1)
lay.addWidget(QtWidgets.QLabel("<b>Chosen Gases</b>"), 0, 2)
lay.addWidget(self.tree_widget, 1, 2)
lay.addWidget(select_button, 2, 2, alignment=QtCore.Qt.AlignCenter)
lay.addWidget(QtWidgets.QLabel("<b>Result:</b>"), 3, 2)
lay.addWidget(self.tree_view, 4, 2)
#QtCore.pyqtSlot()
def add_row(self):
for item in self.listwidget.selectedItems():
data = item.data(ListRole)
text = item.text()
if self.tree_widget.findItems(text, QtCore.Qt.MatchExactly):
continue
it = self.listwidget.takeItem(self.listwidget.row(item))
item = QtWidgets.QTreeWidgetItem()
self.tree_widget.addTopLevelItem(item)
item.setFlags(item.flags() | QtCore.Qt.ItemIsEditable)
for i, e in enumerate(data):
item.setData(i, QtCore.Qt.DisplayRole, e)
#QtCore.pyqtSlot()
def remove_row(self):
rows = [
self.tree_widget.indexOfTopLevelItem(item)
for item in self.tree_widget.selectedItems()
]
for row in sorted(rows, reverse=True):
item = self.tree_widget.takeTopLevelItem(row)
data = []
for i in range(self.tree_widget.columnCount()):
data.append(item.data(i, QtCore.Qt.DisplayRole))
it = QtWidgets.QListWidgetItem(data[0])
it.setData(ListRole, data)
self.listwidget.addItem(it)
if item is not None:
del item
#QtCore.pyqtSlot()
def select(self):
last_number = max(self.proxy_top.number, 0)
number, ok = QtWidgets.QInputDialog.getInt(
None,
"Number of components",
"How many components do you wish to use?",
last_number,
min=-1,
max=self.tree_widget.topLevelItemCount(),
)
if ok:
self.proxy_top.number = number
for i in range(self.tree_widget.topLevelItemCount()):
it = self.tree_widget.topLevelItem(i)
it.setData(2, VisibleRole, False)
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
w = Widget()
w.show()
sys.exit(app.exec_())

Selecting the Values in the Excel Rows Depending on the selection of Check Box in the GUI using Python Tkinter

I have a Excel as Below
|---------------------|------------------|
| Heading 1 | Heading 2 |
|---------------------|------------------|
| Row1 | Value 1 |
|---------------------|------------------|
| Row2 | Value 2 |
|---------------------|------------------|
I am reading from excel and Showing the Values of Heading 1 in the GUI
When I click on submit Button , I need to read the value/text of the CheckBox depending on the selection of the CheckBox and Create XML by using Excel for only selected values
Problem is How can I only select the values in the Excel , depending on the selection of check Box. (But I know how to identify which check box is checked ). But how to relate to Excel is I am facing problem
Note: I Know how to create XML from excel
I know how to identify when submit is clicked
GUI Code:
Config.Py
import tkinter as tk
import xlrd
import GetValueFromExcel
from GetValueFromExcel import ExcelValue
from array import array
from tkinter import *
from tkinter import ttk, Button
from tkinter import *
root = Tk()
class UICreation():
def __init__(self):
print ("I m in __init__")
self.tabControl = ttk.Notebook(root)
self.tab1 = ttk.Frame(self.tabControl)
self.tab2 = ttk.Frame(self.tabControl)
def tabcreation(self):
print ("I M in Tab Creation")
self.tabControl.add(self.tab1 , text="Tab1")
#self.tabControl(self.tab1, text= t)
##self.tabControl(self.tab1, )
self.tabControl.add(self.tab2, text="Tab2")
self.tabControl.grid()
def checkbox(self):
print ("I M in checkBox")
checkBox1 = Checkbutton(self.tab1, text=str(t[0]))
checkBox2 = Checkbutton(self.tab1, text=str(t[1]))
Checkbutton()
checkBox1.grid()
checkBox2.grid()
def button(self):
button = Button(self.tab1 , text="Submit", command=self.OnButtonClick)
button.grid()
def OnButtonClick(self):
print ("I am Working")
if __name__ == '__main__':
ui = UICreation()
ev = GetValueFromExcel.ExcelValue()
ev.readExcelValue()
t = ev.readExcelValue()
print(t)
ui.tabcreation()
ui.checkbox()
ui.button()
#ev = readExcelValue()
root.mainloop()
GetValueFromExcel.py
import xlrd
class ExcelValue():
def __init__(self):
self.wb=xlrd.open_workbook(r"C:\<FilePath>\Filename.xlsx")
#self.ws=self.wb.sheet_by_name("Sheet1")
for sheet in self.wb.sheets():
self.number_of_rows = sheet.nrows
self.number_of_columns = sheet.ncols
def readExcelValue(self):
result_data = []
row_data = []
for sheet in self.wb.sheets():
for curr_row in range(1, self.number_of_rows, 1):
#for curr_col in range(0, self.number_of_columns , 1):
#data = sheet.cell_value(curr_row, curr_col) # Read the data in the current cell
data = sheet.cell_value(curr_row, 0)
#print(data)
row_data.append(data)
result_data.append(row_data)
return result_data[1]
You can pass the value to Checkbutton like this:
def checkbox(self):
print ("I M in checkBox")
checkBox1 = Checkbutton(self.tab1, text=str(t.keys()[0]), variable=t.values()[0])
checkBox2 = Checkbutton(self.tab1, text=str(t.keys()[1]), variable=t.values()[1])
Checkbutton()
checkBox1.grid()
checkBox2.grid()
and you must change readExcelValue, like below:
def readExcelValue(self):
result_data = {}
for sheet in self.wb.sheets():
for curr_row in range(1, self.number_of_rows, 1):
data = sheet.cell_value(curr_row, 0)
value = sheet.cell_value(curr_row, 1)
result_data[data] = value
return result_data

How to place radio button at each row in qtablewidget and allow only one row to select from group of rows?

Below is my table :
In the above table, i have placed the Radiobutton at each row.
In the table, column 'field' has same values in the rows i.e startdate is present in two rows and validity is also repeating in rows.
What i want is to only select only one row consisting validity from the repeating values using radio button. if user selects another value,it must deselect previously selected value.
Below is my code:
class Window(QtGui.QWidget):
def __init__(self, data):
QtGui.QWidget.__init__(self)
self.data=data
rows=len(data)
data1=list()
for d in data:
#print d
#print "ddddddddddddddd",type(d)
d=d.replace('null','""')
d=eval(d)
#print type(d)
data1.append(d)
self.data1=data1
key_list=['file','field','content','refined_content','page_number']
data2=list()
for line in data1:
#print line
d = OrderedDict((k, line[k]) for k in key_list)
data2.append(d)
#print data2
data1=data2
#print data1
keys = ['file','field','content','refined_content','page_number']
keys=list(keys)
columns=len(keys)+1
keys.append("checkbox")
self.table = QtGui.QTableWidget(rows, columns, self)
self.table.setHorizontalHeaderLabels(keys)
self.keys=keys
#print "total columns",columns
#print "total rows",rows
#columns=str(columns)
for column in range(columns-1):
for row in range(rows):
qwidget = QtGui.QWidget()
checkbox = QtGui.QRadioButton()
checkbox.setChecked(False)
qhboxlayout = QtGui.QHBoxLayout(qwidget)
qhboxlayout.addWidget(checkbox)
qhboxlayout.setAlignment(Qt.AlignCenter)
qhboxlayout.setContentsMargins(0, 0, 0, 0)
dic=data1[row]
#print dic
index=int(column)
#print "index",index
value = dic.values()[index]
#print "current row",row
#print "current column",column
self.table.setItem(row, column, QtGui.QTableWidgetItem(str(value)))
#self.table.setItem(row, columns+1, QtGui.QTableWidgetItem(str(row)))
self.table.setCellWidget(row,columns-1 , qwidget)
layout = QtGui.QVBoxLayout(self)
self.button = QtGui.QPushButton()
self.button.setObjectName("loadButton")
self.button.setFixedWidth(100)
self.button.setFixedHeight(30)
self.button.setStyleSheet('color: white;background-color:rgb(0, 76, 153);border-style: outset;border-width: 2px;border-color: rgb(0, 76, 153);border-radius: 10px;alignment:left;')
self.button.setText("Submit")
layout.addWidget(self.table)
layout.addWidget(self.button)
self.button.clicked.connect(self.ButtonClicked)
def ButtonClicked(self,c):
c=self.table.columnCount()
#print "c",c
#print "keys",self.keys
checked_list = []
for i in range(self.table.rowCount()):
#checked_list = []
dic={}
if self.table.cellWidget(i, c-1).findChild(type(QtGui.QRadioButton())).isChecked():
for j in range(c-1):
st=str(self.table.item(i, j).text())
#print j,st
dic[self.keys[j]]=st
#checked_list.append(st)
#print "ddiic",dic
checked_list.append(dic)
print checked_list

How can I print data from my database while in QTableWidget?

How can I print my data from my database (sqlite) into a notepad /word document from my table in my GUI (using the same formatting). Here is my code for the table which is represented on my gui.
class Table(QtGui.QDialog):
def __init__(self):
super(Table, self).__init__()
with sqlite3.connect('database.db') as db:
cursor=db.cursor()
cursor.execute('select* from Receipt Order BY ReceiptID ASC')
title = [cn[0] for cn in cursor.description]
rows = [cn[0] for cn in cursor.description]
cur=cursor.fetchall()
layout = QtGui.QGridLayout()
self.table = QtGui.QTableWidget()
self.setGeometry(500,500,500,400)
qr = self.frameGeometry()
cp = QtGui.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
self.label2=QtGui.QLabel(self)
self.label2.setPixmap(QtGui.QPixmap('receipt_pic.jpg'))
self.label2.setGeometry(0,0,500,400)
self.table.setColumnCount(2)
self.table.setHorizontalHeaderLabels(title)
for i,row in enumerate(cur):
self.table.insertRow(self.table.rowCount())
for j,val in enumerate(row):
self.table.setItem(i, j, QtGui.QTableWidgetItem(str(val)))
layout.addWidget(self.table, 0, 0)
self.setLayout(layout)
self.setWindowTitle('Receipt Table')
I want to be able to click a button which copies this information (which would appear as a table with filled columns and rows) into a seperate notepad file / or any text document (where I can send the table to the printer to be printed).
It would probably be easier to just print the table directly, rather than use an intermediary file.
To do this, you can use a QTextDocument to create a printable representation of the table, and then use the built-in print dialogs to do the rest.
So, first add some buttons:
...
layout.addWidget(self.table, 0, 0, 1, 2)
self.buttonPrint = QtGui.QPushButton('Print', self)
self.buttonPrint.clicked.connect(self.handlePrint)
self.buttonPreview = QtGui.QPushButton('Preview', self)
self.buttonPreview.clicked.connect(self.handlePreview)
layout.addWidget(self.buttonPrint, 1, 0)
layout.addWidget(self.buttonPreview, 1, 1)
self.setLayout(layout)
...
then some handlers for the print and print-preview dialogs:
def handlePrint(self):
dialog = QtGui.QPrintDialog()
if dialog.exec_() == QtGui.QDialog.Accepted:
self.handlePaintRequest(dialog.printer())
def handlePreview(self):
dialog = QtGui.QPrintPreviewDialog()
dialog.paintRequested.connect(self.handlePaintRequest)
dialog.exec_()
and finally some methods for creating the document and printing it:
def handlePaintRequest(self, printer):
document = self.makeTableDocument()
document.print_(printer)
def makeTableDocument(self):
document = QtGui.QTextDocument()
cursor = QtGui.QTextCursor(document)
rows = self.table.rowCount()
columns = self.table.columnCount()
table = cursor.insertTable(rows + 1, columns)
format = table.format()
format.setHeaderRowCount(1)
table.setFormat(format)
format = cursor.blockCharFormat()
format.setFontWeight(QtGui.QFont.Bold)
for column in range(columns):
cursor.setCharFormat(format)
cursor.insertText(
self.table.horizontalHeaderItem(column).text())
cursor.movePosition(QtGui.QTextCursor.NextCell)
for row in range(rows):
for column in range(columns):
cursor.insertText(
self.table.item(row, column).text())
cursor.movePosition(QtGui.QTextCursor.NextCell)
return document
If you prefer to save to a file, you can use QTextDocument.toHtml to dump the table as html.
The printed results are quite basic, but if you want something more fancy, you can always build the document using html/css.
I use this function
def LoadDatabase(self):
self.banco = sqlite3.connect ( 'Vendas.db' )
self.cursor = banco.cursor ( )
query = "SELECT * FROM Produtos"
result = self.banco.execute ( query )
self.listaprodutos.setRowCount ( 0 )
for row_number, row_data in enumerate ( result ):
self.listaprodutos.insertRow ( row_number )
for colum_number, data in enumerate ( row_data ):
self.listaprodutos.setItem ( row_number, colum_number, QtWidgets.QTableWidgetItem ( str ( data ) ) )

Categories

Resources