Hi
How to remove a row from table(QTableView)?
This is my files
orcamento.ui (I use QT Designer to build part of the my GUI)
ui_orcamento
main.py
orcamento_calcada.csv
After press a button and read CSV file, I need choose what row in table I’ll delete.
I try use model code from page 320 martins’s book.
I miss something in this fucntion remove_item_from_table.
import sys
from PySide6 import QtCore, QtGui, QtWidgets
from PySide6.QtCore import Qt, QPersistentModelIndex
from PySide6.QtWidgets import QMessageBox
from ui_orcamento import Ui_mw_orcamento
import pandas as pd
class TableModel(QtCore.QAbstractTableModel):
def __init__(self, data):
super().__init__()
self._data = data
def data(self, index, role):
if role == Qt.DisplayRole:
return self._data[index.row()][index.column()]
def rowCount(self, index):
# The length of the outer list.
return len(self._data)
def columnCount(self, index):
# The following takes the first sub-list, and returns
# the length (only works if all rows are an equal length)
return len(self._data[0])
class MainWindow(QtWidgets.QMainWindow, Ui_mw_orcamento):
def __init__(self):
super().__init__()
self.setupUi(self)
self.show()
self.cb_obras.addItems(['Selecione Um Tipo de Obra','ARQUIBANCADA','CALÇADA','DRENAGEM',
'ESCADARIA','MURO','PAVIMENTAÇÃO','PRAÇA'])
self.cb_tipo_obra.addItems(['Reforma', 'Contrução'])
self.cb_param_calcada.addItems(['...','Meio-Fio', 'Ladrilhio', 'Concreto Polido'])
#self.cb_param_unidade.addItems(['...','m', 'm²', 'm³'])
self.cb_obras.setCurrentIndex(0)
# Connect the currentIndexChanged signal of cb_obras to the changePage slot
self.cb_obras.currentIndexChanged.connect(self.changePage)
self.st_parametro_obras.setCurrentIndex(0)
self.cb_param_calcada.currentIndexChanged.connect(self.auto_complete_und)
# Connect the button signal to add data to the table
self.pb_executar.clicked.connect(self.add_item_to_table)
self.pb_dt_frame.setEnabled(False)
self.pb_dt_frame.clicked.connect(self.load_data_from_csv)
# Create a table of Descriptions
self.tbv_details_calcada
# Remove item from table
self.pb_rm_item.clicked.connect(self.remove_item_from_table)
def auto_complete_und(self):
# Get the current text of cb_param_calcada
selected_calcada = self.cb_param_calcada.currentText()
# Clear the current items in cb_param_unidade
self.cb_param_unidade.clear()
# Define a dictionary mapping calcada types to their units
calcada_units = {
'Meio-Fio': ['m'],
'Ladrilhio': ['m²'],
'Concreto Polido': ['m³']
}
# Check if the selected calcada type is in the dictionary
if selected_calcada in calcada_units:
# Add the corresponding units to cb_param_unidade
self.cb_param_unidade.addItems(calcada_units[selected_calcada])
self.le_valor.setFocus()
# Connect the currentIndexChanged signal of cb_param_calcada to the auto_complete_und slot
#self.cb_param_calcada.currentIndexChanged.connect(self.auto_complete_und)
def changePage(self, index):
# Get the selected item from the combo box
selected_item = self.cb_obras.currentText()
# Create a mapping of item names to page names
page_mapping = {
'Selecione Um Tipo de Obra':0,
'ARQUIBANCADA':1,
'CALÇADA':2,
'DRENAGEM':3,
'ESCADARIA':4,
'MURO':5,
'PAVIMENTAÇÃO':6,
'PRAÇA':7
}
# Get the page index from the mapping
page_index = page_mapping.get(selected_item)
# If a page index was found, show that page
if page_index is not None:
self.st_parametro_obras.setCurrentIndex(page_index)
def add_item_to_table(self):
#Check if fields are filled
if self.cb_param_calcada.currentText() == '...' or self.cb_param_unidade.currentText() == '...' or self.le_valor.text() == '':
# Show a message box to inform the user to fill in all fields
QMessageBox.warning(self, 'Campos Vazios', 'Favor preencher todos os campos.')
return
# Get the values from the controls
param_calcada = self.cb_param_calcada.currentText()
param_unidade = self.cb_param_unidade.currentText()
valor = self.le_valor.text()
# Add the values to the table
new_row = (param_calcada, valor, param_unidade)
# Get the current row count
current_row_count = self.tb_parametro_calcada.rowCount()
# Insert a new row at the end
self.tb_parametro_calcada.insertRow(current_row_count)
# Set the values for the new row
for column, data in enumerate(new_row):
self.tb_parametro_calcada.setItem(current_row_count, column, QtWidgets.QTableWidgetItem(str(data)))
# Resize the columns to fit the contents
self.tb_parametro_calcada.resizeColumnsToContents()
# Clean the controls
self.cb_param_calcada.setCurrentIndex(0)
self.cb_param_unidade.setCurrentIndex(0)
self.le_valor.clear()
tt_linhas = self.tb_parametro_calcada.rowCount()
if tt_linhas == 3:
self.pb_dt_frame.setEnabled(True)
def get_table_data_as_dataframe(self):
# Get the number of rows and columns in the table
num_rows = self.tb_parametro_calcada.rowCount()
num_cols = self.tb_parametro_calcada.columnCount()
# Create an empty list to store the data
data = []
# Iterate through the rows and columns of the table
for row in range(num_rows):
row_data = []
for col in range(num_cols):
# Get the item from the table
item = self.tb_parametro_calcada.item(row, col)
# If the item exists, get its text
if item is not None:
row_data.append(item.text())
else:
# If the item is empty, add an empty string
row_data.append("")
# Append the row data to the list
data.append(row_data)
# Create a Pandas DataFrame from the data
df = pd.DataFrame(data, columns=[self.tb_parametro_calcada.horizontalHeaderItem(col).text() for col in range(num_cols)])
print(df)
# Return the DataFrame
#return df
def load_data_from_csv(self):
# Read data from CSV file
csv_df = pd.read_csv('orcamento_calcada.csv')
# Check that the table view has a model set
if self.tbv_details_calcada.model() is None:
# Create a new model and set it for the table view
self.model = TableModel(csv_df.values.tolist())
self.tbv_details_calcada.setModel(self.model)
# Get the model from the table view
model = self.tbv_details_calcada.model()
# Create an index object for the root of the model
index = QtCore.QModelIndex()
# Insert data into table
for index, row in csv_df.iterrows():
new_row = model.rowCount(index) # Pass the index argument
model.insertRow(new_row)
# Resize columns to fit contents
self.tbv_details_calcada.resizeColumnsToContents()
def remove_item_from_table(self):
# Get the selected rows
if self.tbv_details_calcada.selectionModel().hasSelection():
print("entrando na parte de deleção de linha")
indexs = [QPersistentModelIndex(index) for index in self.tbv_details_calcada.selectionModel().selectedRows()]
for index in indexs:
self.tbv_details_calcada.model().removeRow(index.row())
print("Deletando a linha", index.row())
else:
print("Nenhuma linha selecionada")
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
app.exec()