Module saePisan.controller.FileController
Classes
class FileController (model1, model2, view)-
Expand source code
class FileController: """ Controller class to handle file operations such as loading, saving, and exporting data. Attributes: model1: The first data model. model2: The second data model. view: The view component of the MVC architecture. Methods: __init__(model1, model2, view): Initializes the FileController with the given models and view. load_file(): Loads a CSV or Excel file into the first model. save_data(): Saves data from the first model to a file in various formats (CSV, Excel, JSON, Text). save_data_output(): Saves data from the second model to a file in various formats (CSV, Excel, JSON, Text). save_as_csv(file_path, model): Saves data from the given model as a CSV file. save_as_excel(file_path, model): Saves data from the given model as an Excel file. save_as_json(file_path, model): Saves data from the given model as a JSON file. save_as_txt(file_path, model): Saves data from the given model as a text file with tab-separated values. export_output_to_pdf(): Exports the content of all widgets in the output layout to a PDF file. """ def __init__(self, model1, model2, view): self.model1 = model1 self.model2 = model2 self.view = view # Hubungkan menu bar dengan fungsi self.view.load_action.triggered.connect(self.load_file) self.view.save_action.triggered.connect(self.save_data) self.view.save_data_output_action.triggered.connect(self.save_data_output) self.view.actionLoad_file.triggered.connect(self.load_file) self.view.actionSave_Data.triggered.connect(self.save_data) self.view.save_output_pdf.triggered.connect(self.export_output_to_pdf) self.view.recent_data.triggered.connect(self.view.load_temp_data) self.view.load_secondary_data.triggered.connect(self.load_secondary_data) def open_file(self): """Open file CSV, Excel, atau Text and load to first model""" file_path, selected_filter = QFileDialog.getOpenFileName( self.view, "Open File", "", "CSV Files (*.csv);;Excel Files (*.xlsx);;Text Files (*.txt);;TSV Files (*.tsv);;JSON Files (*.json)" ) if not file_path: # Jika file tidak dipilih return try: if selected_filter in ["CSV Files (*.csv)", "Text Files (*.txt)", "TSV Files (*.tsv)"]: dialog = CSVOptionsDialog(self.view) dialog.file_path = file_path dialog.file_label.setText(f"Selected: {file_path}") dialog.update_preview() file_path, separator, header = dialog.get_csv_options() if not file_path: # Jika file tidak dipilih return if separator == r"\t": # Jika input adalah string literal "\t" separator = "\t" # Baca data dari CSV dengan atau tanpa header if header: data = pl.read_csv(file_path, separator=separator, ignore_errors=True, has_header=True, null_values=["NA", "NULL", "na", "null"]) else: data = pl.read_csv(file_path, separator=separator, ignore_errors=True, has_header=False, null_values=["NA", "NULL", "na", "null"]) data.columns = [f"Column {i+1}" for i in range(data.shape[1])] elif selected_filter == "Excel Files (*.xlsx)": dialog = ExcelOptionsDialog(self.view) dialog.file_path = file_path import pandas as pd xls = pd.ExcelFile(file_path) dialog.sheet_names = xls.sheet_names dialog.sheet_combo.addItems(dialog.sheet_names) dialog.file_label.setText(f"Selected: {file_path}") dialog.update_preview() file_path, selected_sheet, hdr = dialog.get_excel_options() if not file_path or not selected_sheet: # Jika file tidak dipilih return data = pl.read_excel(file_path, sheet_name=selected_sheet, has_header=hdr) elif selected_filter == "JSON Files (*.json)": data = pl.read_json(file_path) return data except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to load file: {str(e)}") def load_file(self): """Load file CSV, Excel, atau Text to first model (Sheet 1) and update tabel.""" data = self.open_file() if data is None: return else: self.model1.set_data(data) self.view.update_table(1, self.model1) QMessageBox.information(self.view, "Success", "File loaded successfully!") self.view.autosave_data() def load_secondary_data(self): """_summary_ Load file CSV, Excel, atau Text to first model (Sheet 2) for secondary data and update tabel. """ main_df = self.model1.get_data() if main_df is None: QMessageBox.warning(self.view, "Warning", "No data loaded in Sheet 1. Please load data first.") return data = self.open_file() if data is None: return class MergeOptionDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Select Merge Method") layout = QVBoxLayout(self) label = QLabel("Select data merge method:", self) self.combo = QComboBox(self) self.combo.addItems(["Horizontal", "Diagonal"]) explanation = QLabel( "<b>Explanation:</b><br>" "<b>Horizontal (Merge Columns):</b> Combines data horizontally by adding columns from the second file to the main file. " "If there are columns with the same name, the columns from the second file will be suffixed with '_duplicate'.<br><br>" "<b>Diagonal (Merge ColRows):</b> Combines data vertically by adding rows where column has same name and adding columns where column has different name from the second file to the main file. " "If the number of columns is different, the columns will be automatically adjusted." ) explanation.setWordWrap(True) ok_btn = QPushButton("OK", self) ok_btn.clicked.connect(self.accept) layout.addWidget(label) layout.addWidget(self.combo) layout.addWidget(ok_btn) layout.addWidget(explanation) layout.setAlignment(Qt.AlignmentFlag.AlignTop) self.setLayout(layout) def get_option(self): return self.combo.currentIndex() dialog = MergeOptionDialog(self.view) if dialog.exec(): option = dialog.get_option() else: return if option == 0: common_cols = set(main_df.columns) & set(data.columns) rename_map = {col: f"{col}_duplicate" for col in common_cols} data = data.rename(rename_map) merged_data = pl.concat([main_df, data], how="horizontal") else: for col in set(main_df.columns) & set(data.columns): main_dtype = main_df[col].dtype try: data = data.with_columns(pl.col(col).cast(main_dtype, strict=False)) except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to cast column '{col}': {e}") merged_data = pl.concat([main_df, data], how="diagonal") self.model1.set_data(merged_data) self.view.update_table(1, self.model1) self.view.autosave_data() def save_data(self): """Save data from the first model (Sheet 1).""" file_path, selected_filter = QFileDialog.getSaveFileName( self.view, "Save File", "", "CSV Files (*.csv);;Excel Files (*.xlsx);;JSON Files (*.json);;Text Files (*.txt)" ) if file_path: try: if selected_filter == "CSV Files (*.csv)": self.save_as_csv(file_path, self.model1) elif selected_filter == "Excel Files (*.xlsx)": self.save_as_excel(file_path, self.model1) elif selected_filter == "JSON Files (*.json)": self.save_as_json(file_path, self.model1) elif selected_filter == "Text Files (*.txt)": self.save_as_txt(file_path, self.model1) QMessageBox.information(self.view, "Success", "File saved successfully!") except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to save file: {str(e)}") def save_data_output(self): """Save data from the first model (Sheet 1).""" file_path, selected_filter = QFileDialog.getSaveFileName( self.view, "Save Output Data", "", "CSV Files (*.csv);;Excel Files (*.xlsx);;JSON Files (*.json);;Text Files (*.txt)" ) if file_path: try: if selected_filter == "CSV Files (*.csv)": self.save_as_csv(file_path, self.model2) elif selected_filter == "Excel Files (*.xlsx)": self.save_as_excel(file_path, self.model2) elif selected_filter == "JSON Files (*.json)": self.save_as_json(file_path, self.model2) elif selected_filter == "Text Files (*.txt)": self.save_as_txt(file_path, self.model2) QMessageBox.information(self.view, "Success", "Output file saved successfully!") except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to save file: {str(e)}") def save_as_csv(self, file_path, model): """Save data as CSV.""" data = model.get_data() data.write_csv(file_path) def save_as_excel(self, file_path, model): """Save data as Excel.""" data = model.get_data() data.write_excel(file_path) def save_as_json(self, file_path, model): """Save data as JSON.""" data = model.get_data() data.write_json(file_path, orient="records", lines=True) def save_as_txt(self, file_path, model): """Save data as file teks.""" data = model.get_data() data.write_csv(file_path, separator="\t") def export_output_to_pdf(self): """Export the content of all widgets in the output layout to a PDF file (menggunakan reportlab untuk tabel).""" file_path, _ = QFileDialog.getSaveFileName( self.view, "Save PDF", "", "PDF Files (*.pdf)" ) if not file_path: return def add_footer(canvas, doc): canvas.saveState() import datetime timestamp = datetime.datetime.now().strftime("%H:%M:%S %d-%m-%Y") footer_text = f"Generated by saePisan at {timestamp}" canvas.setFont("Helvetica-Oblique", 8) width, height = A4 canvas.drawRightString(width - 30, 20, footer_text) canvas.restoreState() doc = SimpleDocTemplate( file_path, pagesize=A4, leftMargin=30, rightMargin=30, topMargin=40, bottomMargin=40 ) frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal') doc.addPageTemplates([PageTemplate(id='footer', frames=frame, onPage=add_footer)]) elements = [] styles = getSampleStyleSheet() normal_style = styles["Normal"] for i in range(self.view.output_layout.count()): item = self.view.output_layout.itemAt(i) widget = item.widget() if widget is None: continue if isinstance(widget, QFrame): for j in range(widget.layout().count()): sub_widget = widget.layout().itemAt(j).widget() if isinstance(sub_widget, QLabel) and "<b>R Script:</b>" in sub_widget.text(): script_box = widget.layout().itemAt(j + 1).widget() text = script_box.toPlainText() elements.append(Paragraph("R Script:", styles["Heading4"])) script_style = ParagraphStyle( name="ScriptStyle", parent=styles["Normal"], fontName="Courier", fontSize=9, leading=12, ) elements.append(Paragraph(text.replace("\n", "<br/>"), script_style)) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QLabel) and "Output" in sub_widget.text(): result_box = widget.layout().itemAt(j + 1).widget() if isinstance(result_box, QTextEdit): text = result_box.toPlainText() elements.append(Paragraph("Output:", styles["Heading4"])) elements.append(Paragraph(text.replace("\n", "<br/>"), normal_style)) elements.append(Spacer(1, 12)) else: elements.append(Paragraph("Output:", styles["Heading4"])) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QTableView): model = sub_widget.model() if model: columns = [model.headerData(col, Qt.Orientation.Horizontal) for col in range(model.columnCount())] data_rows = [] max_col_lens = [len(str(col)) for col in columns] for row in range(model.rowCount()): row_data = [] for row in range(model.rowCount()): row_data = [] for col in range(model.columnCount()): index = model.index(row, col) value = model.data(index) value_str = str(value) try: float_val = float(value) if '.' in value_str and len(value_str) > max_col_lens[col]: value_str = f"{float_val:.5f}" except Exception: pass row_data.append(value_str) if len(value_str) > max_col_lens[col]: max_col_lens[col] = len(value_str) data_rows.append(row_data) if data_rows: table_data = [columns] + data_rows total_len = sum(max_col_lens) max_width = doc.width col_widths = [ max(40, (l / total_len) * max_width) for l in max_col_lens ] table = Table(table_data, repeatRows=1, colWidths=col_widths) table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey), ('TEXTCOLOR', (0, 0), (-1, 0), colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('BOTTOMPADDING', (0, 0), (-1, 0), 6), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ])) elements.append(table) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QLabel) and "<b>Plot:</b>" in sub_widget.text(): for k in range(j + 1, widget.layout().count()): plot_label = widget.layout().itemAt(k).widget() if isinstance(plot_label, QLabel): pixmap = plot_label.pixmap() if pixmap: buffer = QBuffer() buffer.open(QIODevice.OpenModeFlag.ReadWrite) pixmap.toImage().save(buffer, "PNG") buffer.seek(0) # Resize image to fit page width if needed img_width = min(400, doc.width) img_height = 250 * (img_width / 400) # maintain aspect ratio img = Image(io.BytesIO(buffer.data()), width=img_width, height=img_height) elements.append(img) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QLabel): text = sub_widget.text().replace("<b>", "").replace("</b>", "") text = text.replace("<i>", "").replace("</i>", "") if "Summary of" in sub_widget.text(): summary_style = ParagraphStyle( name="SummaryHeading", parent=styles["Heading1"], alignment=TA_CENTER, fontName="Helvetica-Bold" ) elements.append(Paragraph(text, summary_style)) elements.append(Spacer(1, 12)) elif "Generated on" in sub_widget.text(): generated_style = ParagraphStyle( name="GeneratedHeading", parent=styles["Normal"], alignment=2, fontName="Helvetica-Oblique", # Italic fontSize=10, textColor=colors.black ) elements.append(Paragraph(text, generated_style)) elements.append(Spacer(1, 12)) else: elements.append(Paragraph(text, normal_style)) elements.append(Spacer(1, 12)) doc.build(elements) QMessageBox.information(self.view, "Success", "PDF exported successfully!")Controller class to handle file operations such as loading, saving, and exporting data.
Attributes
model1- The first data model.
model2- The second data model.
view- The view component of the MVC architecture.
Methods
init(model1, model2, view): Initializes the FileController with the given models and view. load_file(): Loads a CSV or Excel file into the first model. save_data(): Saves data from the first model to a file in various formats (CSV, Excel, JSON, Text). save_data_output(): Saves data from the second model to a file in various formats (CSV, Excel, JSON, Text). save_as_csv(file_path, model): Saves data from the given model as a CSV file. save_as_excel(file_path, model): Saves data from the given model as an Excel file. save_as_json(file_path, model): Saves data from the given model as a JSON file. save_as_txt(file_path, model): Saves data from the given model as a text file with tab-separated values. export_output_to_pdf(): Exports the content of all widgets in the output layout to a PDF file.
Methods
def export_output_to_pdf(self)-
Expand source code
def export_output_to_pdf(self): """Export the content of all widgets in the output layout to a PDF file (menggunakan reportlab untuk tabel).""" file_path, _ = QFileDialog.getSaveFileName( self.view, "Save PDF", "", "PDF Files (*.pdf)" ) if not file_path: return def add_footer(canvas, doc): canvas.saveState() import datetime timestamp = datetime.datetime.now().strftime("%H:%M:%S %d-%m-%Y") footer_text = f"Generated by saePisan at {timestamp}" canvas.setFont("Helvetica-Oblique", 8) width, height = A4 canvas.drawRightString(width - 30, 20, footer_text) canvas.restoreState() doc = SimpleDocTemplate( file_path, pagesize=A4, leftMargin=30, rightMargin=30, topMargin=40, bottomMargin=40 ) frame = Frame(doc.leftMargin, doc.bottomMargin, doc.width, doc.height, id='normal') doc.addPageTemplates([PageTemplate(id='footer', frames=frame, onPage=add_footer)]) elements = [] styles = getSampleStyleSheet() normal_style = styles["Normal"] for i in range(self.view.output_layout.count()): item = self.view.output_layout.itemAt(i) widget = item.widget() if widget is None: continue if isinstance(widget, QFrame): for j in range(widget.layout().count()): sub_widget = widget.layout().itemAt(j).widget() if isinstance(sub_widget, QLabel) and "<b>R Script:</b>" in sub_widget.text(): script_box = widget.layout().itemAt(j + 1).widget() text = script_box.toPlainText() elements.append(Paragraph("R Script:", styles["Heading4"])) script_style = ParagraphStyle( name="ScriptStyle", parent=styles["Normal"], fontName="Courier", fontSize=9, leading=12, ) elements.append(Paragraph(text.replace("\n", "<br/>"), script_style)) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QLabel) and "Output" in sub_widget.text(): result_box = widget.layout().itemAt(j + 1).widget() if isinstance(result_box, QTextEdit): text = result_box.toPlainText() elements.append(Paragraph("Output:", styles["Heading4"])) elements.append(Paragraph(text.replace("\n", "<br/>"), normal_style)) elements.append(Spacer(1, 12)) else: elements.append(Paragraph("Output:", styles["Heading4"])) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QTableView): model = sub_widget.model() if model: columns = [model.headerData(col, Qt.Orientation.Horizontal) for col in range(model.columnCount())] data_rows = [] max_col_lens = [len(str(col)) for col in columns] for row in range(model.rowCount()): row_data = [] for row in range(model.rowCount()): row_data = [] for col in range(model.columnCount()): index = model.index(row, col) value = model.data(index) value_str = str(value) try: float_val = float(value) if '.' in value_str and len(value_str) > max_col_lens[col]: value_str = f"{float_val:.5f}" except Exception: pass row_data.append(value_str) if len(value_str) > max_col_lens[col]: max_col_lens[col] = len(value_str) data_rows.append(row_data) if data_rows: table_data = [columns] + data_rows total_len = sum(max_col_lens) max_width = doc.width col_widths = [ max(40, (l / total_len) * max_width) for l in max_col_lens ] table = Table(table_data, repeatRows=1, colWidths=col_widths) table.setStyle(TableStyle([ ('BACKGROUND', (0, 0), (-1, 0), colors.lightgrey), ('TEXTCOLOR', (0, 0), (-1, 0), colors.black), ('ALIGN', (0, 0), (-1, -1), 'LEFT'), ('FONTNAME', (0, 0), (-1, 0), 'Helvetica-Bold'), ('FONTSIZE', (0, 0), (-1, -1), 8), ('BOTTOMPADDING', (0, 0), (-1, 0), 6), ('GRID', (0, 0), (-1, -1), 0.5, colors.grey), ('VALIGN', (0, 0), (-1, -1), 'TOP'), ])) elements.append(table) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QLabel) and "<b>Plot:</b>" in sub_widget.text(): for k in range(j + 1, widget.layout().count()): plot_label = widget.layout().itemAt(k).widget() if isinstance(plot_label, QLabel): pixmap = plot_label.pixmap() if pixmap: buffer = QBuffer() buffer.open(QIODevice.OpenModeFlag.ReadWrite) pixmap.toImage().save(buffer, "PNG") buffer.seek(0) # Resize image to fit page width if needed img_width = min(400, doc.width) img_height = 250 * (img_width / 400) # maintain aspect ratio img = Image(io.BytesIO(buffer.data()), width=img_width, height=img_height) elements.append(img) elements.append(Spacer(1, 12)) elif isinstance(sub_widget, QLabel): text = sub_widget.text().replace("<b>", "").replace("</b>", "") text = text.replace("<i>", "").replace("</i>", "") if "Summary of" in sub_widget.text(): summary_style = ParagraphStyle( name="SummaryHeading", parent=styles["Heading1"], alignment=TA_CENTER, fontName="Helvetica-Bold" ) elements.append(Paragraph(text, summary_style)) elements.append(Spacer(1, 12)) elif "Generated on" in sub_widget.text(): generated_style = ParagraphStyle( name="GeneratedHeading", parent=styles["Normal"], alignment=2, fontName="Helvetica-Oblique", # Italic fontSize=10, textColor=colors.black ) elements.append(Paragraph(text, generated_style)) elements.append(Spacer(1, 12)) else: elements.append(Paragraph(text, normal_style)) elements.append(Spacer(1, 12)) doc.build(elements) QMessageBox.information(self.view, "Success", "PDF exported successfully!")Export the content of all widgets in the output layout to a PDF file (menggunakan reportlab untuk tabel).
def load_file(self)-
Expand source code
def load_file(self): """Load file CSV, Excel, atau Text to first model (Sheet 1) and update tabel.""" data = self.open_file() if data is None: return else: self.model1.set_data(data) self.view.update_table(1, self.model1) QMessageBox.information(self.view, "Success", "File loaded successfully!") self.view.autosave_data()Load file CSV, Excel, atau Text to first model (Sheet 1) and update tabel.
def load_secondary_data(self)-
Expand source code
def load_secondary_data(self): """_summary_ Load file CSV, Excel, atau Text to first model (Sheet 2) for secondary data and update tabel. """ main_df = self.model1.get_data() if main_df is None: QMessageBox.warning(self.view, "Warning", "No data loaded in Sheet 1. Please load data first.") return data = self.open_file() if data is None: return class MergeOptionDialog(QDialog): def __init__(self, parent=None): super().__init__(parent) self.setWindowTitle("Select Merge Method") layout = QVBoxLayout(self) label = QLabel("Select data merge method:", self) self.combo = QComboBox(self) self.combo.addItems(["Horizontal", "Diagonal"]) explanation = QLabel( "<b>Explanation:</b><br>" "<b>Horizontal (Merge Columns):</b> Combines data horizontally by adding columns from the second file to the main file. " "If there are columns with the same name, the columns from the second file will be suffixed with '_duplicate'.<br><br>" "<b>Diagonal (Merge ColRows):</b> Combines data vertically by adding rows where column has same name and adding columns where column has different name from the second file to the main file. " "If the number of columns is different, the columns will be automatically adjusted." ) explanation.setWordWrap(True) ok_btn = QPushButton("OK", self) ok_btn.clicked.connect(self.accept) layout.addWidget(label) layout.addWidget(self.combo) layout.addWidget(ok_btn) layout.addWidget(explanation) layout.setAlignment(Qt.AlignmentFlag.AlignTop) self.setLayout(layout) def get_option(self): return self.combo.currentIndex() dialog = MergeOptionDialog(self.view) if dialog.exec(): option = dialog.get_option() else: return if option == 0: common_cols = set(main_df.columns) & set(data.columns) rename_map = {col: f"{col}_duplicate" for col in common_cols} data = data.rename(rename_map) merged_data = pl.concat([main_df, data], how="horizontal") else: for col in set(main_df.columns) & set(data.columns): main_dtype = main_df[col].dtype try: data = data.with_columns(pl.col(col).cast(main_dtype, strict=False)) except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to cast column '{col}': {e}") merged_data = pl.concat([main_df, data], how="diagonal") self.model1.set_data(merged_data) self.view.update_table(1, self.model1) self.view.autosave_data()summary Load file CSV, Excel, atau Text to first model (Sheet 2) for secondary data and update tabel.
def open_file(self)-
Expand source code
def open_file(self): """Open file CSV, Excel, atau Text and load to first model""" file_path, selected_filter = QFileDialog.getOpenFileName( self.view, "Open File", "", "CSV Files (*.csv);;Excel Files (*.xlsx);;Text Files (*.txt);;TSV Files (*.tsv);;JSON Files (*.json)" ) if not file_path: # Jika file tidak dipilih return try: if selected_filter in ["CSV Files (*.csv)", "Text Files (*.txt)", "TSV Files (*.tsv)"]: dialog = CSVOptionsDialog(self.view) dialog.file_path = file_path dialog.file_label.setText(f"Selected: {file_path}") dialog.update_preview() file_path, separator, header = dialog.get_csv_options() if not file_path: # Jika file tidak dipilih return if separator == r"\t": # Jika input adalah string literal "\t" separator = "\t" # Baca data dari CSV dengan atau tanpa header if header: data = pl.read_csv(file_path, separator=separator, ignore_errors=True, has_header=True, null_values=["NA", "NULL", "na", "null"]) else: data = pl.read_csv(file_path, separator=separator, ignore_errors=True, has_header=False, null_values=["NA", "NULL", "na", "null"]) data.columns = [f"Column {i+1}" for i in range(data.shape[1])] elif selected_filter == "Excel Files (*.xlsx)": dialog = ExcelOptionsDialog(self.view) dialog.file_path = file_path import pandas as pd xls = pd.ExcelFile(file_path) dialog.sheet_names = xls.sheet_names dialog.sheet_combo.addItems(dialog.sheet_names) dialog.file_label.setText(f"Selected: {file_path}") dialog.update_preview() file_path, selected_sheet, hdr = dialog.get_excel_options() if not file_path or not selected_sheet: # Jika file tidak dipilih return data = pl.read_excel(file_path, sheet_name=selected_sheet, has_header=hdr) elif selected_filter == "JSON Files (*.json)": data = pl.read_json(file_path) return data except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to load file: {str(e)}")Open file CSV, Excel, atau Text and load to first model
def save_as_csv(self, file_path, model)-
Expand source code
def save_as_csv(self, file_path, model): """Save data as CSV.""" data = model.get_data() data.write_csv(file_path)Save data as CSV.
def save_as_excel(self, file_path, model)-
Expand source code
def save_as_excel(self, file_path, model): """Save data as Excel.""" data = model.get_data() data.write_excel(file_path)Save data as Excel.
def save_as_json(self, file_path, model)-
Expand source code
def save_as_json(self, file_path, model): """Save data as JSON.""" data = model.get_data() data.write_json(file_path, orient="records", lines=True)Save data as JSON.
def save_as_txt(self, file_path, model)-
Expand source code
def save_as_txt(self, file_path, model): """Save data as file teks.""" data = model.get_data() data.write_csv(file_path, separator="\t")Save data as file teks.
def save_data(self)-
Expand source code
def save_data(self): """Save data from the first model (Sheet 1).""" file_path, selected_filter = QFileDialog.getSaveFileName( self.view, "Save File", "", "CSV Files (*.csv);;Excel Files (*.xlsx);;JSON Files (*.json);;Text Files (*.txt)" ) if file_path: try: if selected_filter == "CSV Files (*.csv)": self.save_as_csv(file_path, self.model1) elif selected_filter == "Excel Files (*.xlsx)": self.save_as_excel(file_path, self.model1) elif selected_filter == "JSON Files (*.json)": self.save_as_json(file_path, self.model1) elif selected_filter == "Text Files (*.txt)": self.save_as_txt(file_path, self.model1) QMessageBox.information(self.view, "Success", "File saved successfully!") except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to save file: {str(e)}")Save data from the first model (Sheet 1).
def save_data_output(self)-
Expand source code
def save_data_output(self): """Save data from the first model (Sheet 1).""" file_path, selected_filter = QFileDialog.getSaveFileName( self.view, "Save Output Data", "", "CSV Files (*.csv);;Excel Files (*.xlsx);;JSON Files (*.json);;Text Files (*.txt)" ) if file_path: try: if selected_filter == "CSV Files (*.csv)": self.save_as_csv(file_path, self.model2) elif selected_filter == "Excel Files (*.xlsx)": self.save_as_excel(file_path, self.model2) elif selected_filter == "JSON Files (*.json)": self.save_as_json(file_path, self.model2) elif selected_filter == "Text Files (*.txt)": self.save_as_txt(file_path, self.model2) QMessageBox.information(self.view, "Success", "Output file saved successfully!") except Exception as e: QMessageBox.critical(self.view, "Error", f"Failed to save file: {str(e)}")Save data from the first model (Sheet 1).