Hidden “ADD” button keeps reappearing when new rows are added to the PyQt5 table using “Enter Details”
This is the code:
import os
import sys
from PyQt5.QtWidgets import (
QApplication, QWidget, QLabel, QLineEdit, QPushButton, QVBoxLayout, QDateEdit, QTableWidget, QDateTimeEdit,
QGroupBox, QFileDialog,
QTableWidgetItem, QHeaderView, QMessageBox, QDesktopWidget, QDialog, QHBoxLayout, QSplitter, QInputDialog,
QDialogButtonBox
)
from PyQt5.QtGui import QPalette, QPainterPath, QPainter, QImage
from PyQt5.QtCore import Qt
from PyQt5.QtCore import Qt, QDate
import openpyxl
app = QApplication(sys.argv)
#app.setStyleSheet(open("employee_details.css").read()) # Load the CSS here
class EmployeeDetailsApp(QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle("Employee Details and Age")
screen = QDesktopWidget().screenGeometry()
width = int(screen.width() * 1)
height = int(screen.height() * 1)
self.setGeometry(int((screen.width() - width) / 2), int((screen.height() - height) / 2), width, height)
self.layout = QVBoxLayout(self)
# Create a splitter
splitter = QSplitter(Qt.Horizontal)
# Left side (Input fields and buttons)
left_widget = QWidget(splitter)
left_layout = QVBoxLayout(left_widget)
self.create_input_fields(left_layout)
# Right side (Table)
right_widget = QWidget(splitter)
right_layout = QVBoxLayout(right_widget)
self.create_table(right_layout)
# Add the splitter to the main layout
self.layout.addWidget(splitter)
# Set the splitter ratio to 20% - 80%
sizes = [int(width * 0.25), int(width * 0.75)]
splitter.setSizes(sizes)
self.button_widgets = {}
self.employee_details = None
def create_input_fields(self, layout):
self.doc_name_label = QLabel("Document Name:")
self.doc_name_field = QLineEdit()
self.doc_number_label = QLabel("Document Number:")
self.doc_number_field = QLineEdit()
self.name_label = QLabel("Part Number:")
self.name_field = QLineEdit()
self.issue_date_label = QLabel("Issue Date:")
self.issue_date_field = QDateEdit()
self.issue_date_field.setDate(QDate.currentDate()) # Set default value to today's date
self.issue_date_field.setCalendarPopup(True)
self.initial_date = self.issue_date_field.date()
self.document_type_label = QLabel("Document Type:")
self.document_type_field = QLineEdit()
self.issued_by_label = QLabel("Issued By:")
self.issued_by_field = QLineEdit()
self.signature_label_issued = QLabel("Signature (Issued):")
self.signature_button_issued = QPushButton("")
self.signature_button_issued.clicked.connect(self.open_signature_dialog_issued)
self.received_by_label = QLabel("Received By:")
self.received_by_field = QLineEdit()
self.signature_label_received = QLabel("Signature (Received):")
self.signature_button_received = QPushButton("")
self.signature_button_received.clicked.connect(self.open_signature_dialog_received)
self.remark_label = QLabel("Remark:")
self.remark_field = QLineEdit()
self.enter_button = QPushButton("Enter Details")
self.enter_button.clicked.connect(self.enter_details)
layout.addWidget(self.doc_name_label)
layout.addWidget(self.doc_name_field)
layout.addWidget(self.doc_number_label)
layout.addWidget(self.doc_number_field)
layout.addWidget(self.name_label)
layout.addWidget(self.name_field)
layout.addWidget(self.issue_date_label)
layout.addWidget(self.issue_date_field)
layout.addWidget(self.document_type_label)
layout.addWidget(self.document_type_field)
layout.addWidget(self.issued_by_label)
layout.addWidget(self.issued_by_field)
layout.addWidget(self.signature_label_issued)
layout.addWidget(self.signature_button_issued)
layout.addWidget(self.received_by_label)
layout.addWidget(self.received_by_field)
layout.addWidget(self.signature_label_received)
layout.addWidget(self.signature_button_received)
layout.addWidget(self.remark_label)
layout.addWidget(self.remark_field)
layout.addWidget(self.enter_button)
def create_table(self, layout):
self.employee_table = QTableWidget()
self.employee_table.setColumnCount(10)
self.employee_table.setHorizontalHeaderLabels([
"Document Name", "Document Number", "Part Number", "Issue Date", "Document Type",
"Issued By", "Signature (Issued)", "Received By", "Signature(Received)", "Remark"
])
# Set the size of each column
column_sizes = [150, 150, 100, 100, 120, 120, 120, 150, 150, 200] # Adjust sizes as needed
for col, size in enumerate(column_sizes):
self.employee_table.setColumnWidth(col, size)
#self.employee_table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)
layout.addWidget(self.employee_table)
# Create a QHBoxLayout for side-by-side placement
hbox_layout = QHBoxLayout()
# Create a QHBoxLayout for buttons
actions_groupbox = QGroupBox("Actions")
actions_layout = QVBoxLayout(actions_groupbox)
self.save_button = QPushButton("Save to Excel")
self.view_excel_data_button = QPushButton("View Excel Data")
self.refresh_button = QPushButton("Refresh")
actions_layout.addWidget(self.save_button)
actions_layout.addWidget(self.view_excel_data_button)
actions_layout.addWidget(self.refresh_button)
hbox_layout.addWidget(actions_groupbox)
self.save_button.clicked.connect(self.save_to_excel)
self.view_excel_data_button.clicked.connect(self.view_excel_data)
self.refresh_button.clicked.connect(self.refresh_table)
# Create a QGroupBox for "Filter" section
filter_groupbox = QGroupBox("Filter")
filter_layout = QVBoxLayout(filter_groupbox)
# Add filter-related widgets
self.start_date_label = QLabel("Start Date:")
self.start_date_field = QDateEdit()
self.start_date_field.setDisplayFormat("yyyy-MM-dd")
self.start_date_field.setCalendarPopup(True)
self.end_date_label = QLabel("End Date:")
self.end_date_field = QDateEdit()
self.end_date_field.setDisplayFormat("yyyy-MM-dd")
self.end_date_field.setCalendarPopup(True)
self.document_name_label = QLabel("Document Name:")
self.document_name_field = QLineEdit()
self.filter_apply_button = QPushButton("Apply Filter")
self.filter_apply_button.clicked.connect(self.apply_filter)
filter_layout.addWidget(self.start_date_label)
filter_layout.addWidget(self.start_date_field)
filter_layout.addWidget(self.end_date_label)
filter_layout.addWidget(self.end_date_field)
filter_layout.addWidget(self.document_name_label)
filter_layout.addWidget(self.document_name_field)
filter_layout.addWidget(self.filter_apply_button)
hbox_layout.addWidget(filter_groupbox)
layout.addLayout(hbox_layout)
def apply_filter(self):
# Get the filter criteria
start_date = self.start_date_field.date().toString("yyyy-MM-dd")
end_date = self.end_date_field.date().toString("yyyy-MM-dd")
document_name = self.document_name_field.text().lower()
# Filter data based on criteria
filtered_data = []
for row in range(self.employee_table.rowCount()):
row_data = [self.employee_table.item(row, col).text().lower() for col in
range(self.employee_table.columnCount())]
row_visible = (
(start_date <= row_data[3] <= end_date) and # Assuming date column is at index 3
(document_name in row_data[0])
)
if row_visible:
filtered_data.append(row_data)
# Create a new window to display the filtered data
filter_result_window = FilterResultWindow(filtered_data)
filter_result_window.exec_()
def set_input_width(self, widget, percentage):
width = int(self.width() * percentage)
widget.setFixedWidth(width)
def open_signature_dialog_issued(self, row):
dialog = SignatureDialogIssued(self)
result = dialog.exec_()
if result == QDialog.Accepted:
self.hideiss(row)
signature_text = dialog.get_signature()
def open_signature_dialog_received(self, row):
dialog = SignatureDialogReceived(self)
result = dialog.exec_()
if result == QDialog.Accepted:
self.hiderec(row)
signature_text = dialog.get_signature()
def hiderec(self, row):
self.button_widgets[row]["received"].hide()
def hideiss(self, row):
self.button_widgets[row]["issued"].hide()
def enter_details(self):
doc_name = self.doc_name_field.text()
doc_number = self.doc_number_field.text()
part_number = self.name_field.text()
issue_date = self.issue_date_field.date().toString("yyyy-MM-dd")
document_type = self.document_type_field.text()
issued_by = self.issued_by_field.text()
signature_issued = self.signature_button_issued.text()
received_by = self.received_by_field.text()
signature_received = self.signature_button_received.text()
remark = self.remark_field.text()
self.employee_details = (
doc_name, doc_number, part_number, issue_date, document_type, issued_by, signature_issued, received_by,
signature_received, remark)
row_count = self.employee_table.rowCount()
print(row_count)
self.employee_table.insertRow(row_count)
for col, value in enumerate(self.employee_details):
self.employee_table.setItem(row_count, col, QTableWidgetItem(value))
if col == 6:
self.btn_widget1 = self.create_button_widgetissued(row_count, col)
self.employee_table.setCellWidget(row_count, col, self.btn_widget1)
elif col == 8:
self.btn_widget2 = self.create_button_widgetrecieved(row_count, col)
self.employee_table.setCellWidget(row_count, col, self.btn_widget2)
self.employee_table.setRowHeight(row_count, 80)
# Store the button widgets in the dictionary
self.button_widgets[row_count] = {"issued": self.btn_widget1, "received": self.btn_widget2}
self.clear_fields()
def create_button_widgetissued(self, row, col):
button_widget = QWidget(self)
layout = QVBoxLayout(button_widget)
add_button = QPushButton("Add", button_widget)
add_button.clicked.connect(lambda _, r=row: self.open_signature_dialog_issued(r))
layout.addWidget(add_button)
layout.setAlignment(add_button, Qt.AlignCenter)
return button_widget
def create_button_widgetrecieved(self, row, col):
button_widget = QWidget(self)
layout = QVBoxLayout(button_widget)
add_button = QPushButton("Add", button_widget)
add_button.clicked.connect(lambda _, r=row: self.open_signature_dialog_received(r))
layout.addWidget(add_button)
layout.setAlignment(add_button, Qt.AlignCenter)
return button_widget
def save_to_excel(self):
workbook = openpyxl.Workbook()
sheet = workbook.active
for row in range(self.employee_table.rowCount()):
for col in range(self.employee_table.columnCount()):
value = self.employee_table.item(row, col).text()
sheet[chr(ord('A') + col) + str(row + 1)] = value
workbook.save("employee_data.xlsx")
self.clear_fields()
def view_excel_data(self):
try:
os.startfile("employee_data.xlsx")
except FileNotFoundError:
QMessageBox.warning(self, "Error", "Employee data file not found.")
def refresh_table(self):
self.employee_table.setRowCount(0)
def clear_fields(self):
self.doc_name_field.clear()
self.doc_number_field.clear()
self.name_field.clear()
self.issue_date_field.setDate(self.initial_date)
self.document_type_field.clear()
self.issued_by_field.clear()
self.received_by_field.clear()
self.signature_button_issued.setText("")
self.signature_button_received.setText("")
self.remark_field.clear()
self.employee_details = None
class FilterResultWindow(QDialog):
def __init__(self, filtered_data, parent=None):
super().__init__(parent)
self.setWindowTitle("Filter Result")
self.layout = QVBoxLayout()
self.table = QTableWidget()
self.table.setColumnCount(10)
self.table.setHorizontalHeaderLabels([
"Document Name", "Document Number", "Part Number", "Issue Date", "Document Type",
"Issued By", "Signature (Issued)", "Received By", "Signature(Received)", "Remark"
])
# Populate the filtered data into the table
self.table.setRowCount(len(filtered_data))
for row, data_row in enumerate(filtered_data):
for col, value in enumerate(data_row):
self.table.setItem(row, col, QTableWidgetItem(value))
self.layout.addWidget(self.table)
# Add a button to save filtered data to a new Excel file
self.save_filtered_button = QPushButton("Save Filtered Data")
self.save_filtered_button.clicked.connect(self.save_filtered_data)
self.layout.addWidget(self.save_filtered_button)
self.setLayout(self.layout)
def save_filtered_data(self):
workbook = openpyxl.Workbook()
sheet = workbook.active
# Write header row
header = [
"Document Name", "Document Number", "Part Number", "Issue Date", "Document Type",
"Issued By", "Signature (Issued)", "Received By", "Signature(Received)", "Remark"
]
for col, value in enumerate(header):
sheet[chr(ord('A') + col) + "1"] = value
# Write data rows
for row, data_row in enumerate(self.get_table_data()):
for col, value in enumerate(data_row):
sheet[chr(ord('A') + col) + str(row + 2)] = value
# Save the workbook
try:
file_dialog = QFileDialog(self)
file_dialog.setAcceptMode(QFileDialog.AcceptSave)
file_path, _ = file_dialog.getSaveFileName(self, "Save Filtered Data", "", "Excel Files (*.xlsx)")
if file_path:
workbook.save(file_path)
QMessageBox.information(self, "Saved", "Filtered data saved successfully.")
except Exception as e:
QMessageBox.warning(self, "Error", f"An error occurred: {str(e)}")
def get_table_data(self):
# Helper function to get data from the table
table_data = []
for row in range(self.table.rowCount()):
row_data = [self.table.item(row, col).text() for col in range(self.table.columnCount())]
table_data.append(row_data)
return table_data
class DateInputDialog(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Date Filter")
layout = QVBoxLayout(self)
self.date_edit = QDateTimeEdit(self)
self.date_edit.setDisplayFormat("yyyy-MM-dd")
layout.addWidget(self.date_edit)
buttons = QDialogButtonBox(QDialogButtonBox.Ok | QDialogButtonBox.Cancel, Qt.Horizontal, self)
buttons.accepted.connect(self.accept)
buttons.rejected.connect(self.reject)
layout.addWidget(buttons)
def get_date(self):
return self.date_edit.date()
class SignatureDialogIssued(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Signature Issued By")
self.layout = QVBoxLayout()
self.signature_label = QLabel("Please draw your signature:")
self.signature_widget = SignatureWidget(self)
self.ok_button = QPushButton("OK")
self.cancel_button = QPushButton("Cancel")
self.ok_button.clicked.connect(self.accept)
self.cancel_button.clicked.connect(self.reject)
self.layout.addWidget(self.signature_label)
self.layout.addWidget(self.signature_widget)
self.layout.addWidget(self.ok_button)
self.layout.addWidget(self.cancel_button)
self.setLayout(self.layout)
def get_signature(self):
return self.signature_widget.get_signatureissued()
class SignatureDialogReceived(QDialog):
def __init__(self, parent=None):
super().__init__(parent)
self.setWindowTitle("Signature (Received By)")
self.layout = QVBoxLayout()
self.signature_label = QLabel("Please draw your signature:")
self.signature_widget = SignatureWidget(self)
self.ok_button = QPushButton("OK")
self.cancel_button = QPushButton("Cancel")
self.ok_button.clicked.connect(self.accept)
self.cancel_button.clicked.connect(self.reject)
self.layout.addWidget(self.signature_label)
self.layout.addWidget(self.signature_widget)
self.layout.addWidget(self.ok_button)
self.layout.addWidget(self.cancel_button)
self.setLayout(self.layout)
def get_signature(self):
return self.signature_widget.get_signaturerecieved()
class SignatureWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setFixedSize(300, 100)
self.path = QPainterPath()
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing, True)
painter.drawPath(self.path)
def mousePressEvent(self, event):
self.path.moveTo(event.pos())
def mouseMoveEvent(self, event):
self.path.lineTo(event.pos())
self.update()
def get_signatureissued(self):
image = QImage(self.size(), QImage.Format_ARGB32)
image.fill(Qt.white)
painter = QPainter(image)
painter.setRenderHint(QPainter.Antialiasing, True)
painter.drawPath(self.path)
painter.end()
image.save("signatureissued.png")
return "signatureissued.png"
def get_signaturerecieved(self):
image = QImage(self.size(), QImage.Format_ARGB32)
image.fill(Qt.white)
painter = QPainter(image)
painter.setRenderHint(QPainter.Antialiasing, True)
painter.drawPath(self.path)
painter.end()
image.save("signaturerecieved.png")
return "signaturerecieved.png"
if __name__ == "__main__":
# app = QApplication(sys.argv)
window = EmployeeDetailsApp()
window.show()
sys.exit(app.exec_())
- I want the ADD button to stay hidden even if I add new rows to the table.
Some info abt the code
-
Table is created in “create_table” function
-
ADD button in the table is created in “create_button_widgetissued” and “create_button_widgetrecieved” function
-
New rows and buttons are added to the table in “enter_details” function
-
Signature dialog box is opened in “open_signature_dialog_issued” and open_signature_dialog_recieved" function. (it uses SignatureDialog class in the botttom of the code)
-
“hiderec” and “hideiss” functions hide the ADD buttons in the table.
-
Visibility status of buttons is stored in “button_widgets” list.
I’ve literally tried eveything. Googled it, used CHATGPT, nothing seems to work.