Anonymous
Nuitka & PyQt6 spezifizieren Importe zur Reduzierung der Exe-Größe (derzeit ~1 GB)
Post
by Anonymous » 22 Dec 2025, 20:25
Ich arbeite an einem Projekt zur Entwicklung einer einfachen App, die auf einem Python-Skript zur Datenanalyse basiert, PyQt6 zum Formatieren der App und Nuitka zum Erstellen einer Exe-Datei verwende. (Ja, ich habe versucht, PyInstaller zu verwenden. Das Antivirenprogramm meines Unternehmens blockiert es ständig.)
Die App ruft mit Pandas Daten aus einer CSV ab, transformiert die Daten mit SciPy und zeichnet die Daten dann mit MatPlotLib auf.
Ich versuche, die Größe der Exe-Datei zu reduzieren, damit sie problemlos in meinem Labor geteilt werden kann. Irgendwelche Vorschläge, wie man die Importe reduzieren und die Größe der Exe-Datei reduzieren kann? Ich werde unten einige Auszüge einfügen:
Code: Select all
from sys import argv, exit
from PyQt6.QtWidgets import QApplication
from gui_app import PyQtApp
if __name__== "__main__":
app = QApplication(argv)
main_app_instance = PyQtApp()
main_app_instance.show()
try:
exit(app.exec())
except SystemExit:
print('Closing Window...')
Code: Select all
import sys
from os import path, getcwd
from pandas import DataFrame, read_csv
from PyQt6.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QLineEdit, QPushButton, QFileDialog, QTableView, QTextEdit, QGroupBox
)
from PyQt6.QtGui import QIcon, QPixmap
from data_model import PandasModel
from data_analyzer import analyze_cof_data
from graph_widget import MplGraphWidget
def resource_path(relative_path):
if hasattr(sys, "-MEIPASS"):
return path.join(sys.MEIPASS, relative_path)
return path.join(path.abspath("./images/"), relative_path)
class PyQtApp(QWidget):
# Defines main window
def __init__(self):
super().__init__()
# Creates dataframe
self.df = None
# Window title
self.title = 'RCP Analysis'
# Window dimensions
self.left = 0
self.top = 0
self.width = 600
self.height = 900
# Sets up main window
self.setWindowTitle(self.title)
self.setGeometry(self.left, self.top, self.width, self.height)
self.layout = QVBoxLayout()
self.setLayout(self.layout)
# Displays widgets in init_ui
self.init_ui()
# Connects to file browser and searches for CSV files
def getFileName(self):
file_filter = 'Data File (*.csv)'
filePath, _ = QFileDialog.getOpenFileName(
parent=self,
caption='Select a data file',
directory=getcwd(),
filter=file_filter
)
if filePath:
self.dataSourceField.setText(filePath)
# Loads data from CSV into dataframe
def retrieveDataset(self):
# Defines path to source file
self.urlSource = self.dataSourceField.text()
if not self.urlSource or not path.exists(self.urlSource):
self.statusLabel.setText("Invalid filepath provided or file does not exist.")
return
try:
# Reads data from CSV
self.df = read_csv(
self.urlSource,
header=6,
usecols=[0,1],
names=["Time", "CoF"]
)
# Writes data into dataframe table
if isinstance(self.df, DataFrame):
self.df = self.df.dropna()
self.model = PandasModel(self.df)
self.table.setModel(self.model)
self.statusLabel.setText(f"Successfully loaded {len(self.df)} rows.")
self.table.horizontalHeader().setStretchLastSection(True)
else:
self.statusLabel.setText(f"Error: Loaded object is not a DataFrame (Type: {type(self.df)})")
except Exception as e:
self.statusLabel.setText(f"Erro loading file: {e}")
print(f"Error details: {e}")
# Begins data analysis
def launchAnalysis(self):
# Ensures data exists
if self.df is not None and isinstance(self.df, DataFrame) and not self.df.empty:
self.statusLabel.setText("Starting data analysis...")
self.results_text.clear()
try:
# Runs analysis
results = analyze_cof_data(self.df)
# Writes results in results text box
for line in results['summary']:
self.results_text.append(line)
# Graphs data in widget
self.graph_widget.plot_data(self.df["Time"], self.df["CoF"], "Raw CoF Data Plot")
# Success statement
self.statusLabel.setText("Analysis complete.")
print(f"Analyze complete. CoF: {results['avg_CoF']: .4f}, STDEV: {results['stdev_np']: .4f}")
# Error statement
except Exception as e:
self.statusLabel.setText(f"Error during analysis: {e}")
print(f"Error during analysis details: {e}")
# Failure statement
else:
self.statusLabel.setText("Cannot analyze: No data loaded.")
print("No data to analyze")
# Sets up user interface
def init_ui(self):
# Icon
icon = resource_path("QH_icon.ico")
self.setWindowIcon(QIcon(icon))
# Logo
logo = resource_path("QH_logo.png")
pixmap = QPixmap(logo)
logo_label = QLabel()
logo_label.setPixmap(pixmap)
self.layout.addWidget(logo_label)
# Defines UI layout
sourceLayout = QHBoxLayout()
self.layout.addLayout(sourceLayout)
# File browser widget
label = QLabel('&Data Source:')
self.dataSourceField = QLineEdit()
label.setBuddy(self.dataSourceField)
# Action buttons
buttonBrowse = QPushButton('&Browse', clicked=self.getFileName)
buttonRetrieve = QPushButton('&Get Data', clicked=self.retrieveDataset)
buttonLaunch = QPushButton('&Analyze', clicked=self.launchAnalysis)
# Organizes layout
sourceLayout.addWidget(label)
sourceLayout.addWidget(self.dataSourceField)
sourceLayout.addWidget(buttonBrowse)
sourceLayout.addWidget(buttonRetrieve)
# Table widget and "Analyze" button
self.table = QTableView()
self.layout.addWidget(self.table, 1)
self.layout.addWidget(buttonLaunch)
# Graph widget
self.graph_widget = MplGraphWidget(self)
self.layout.addWidget(self.graph_widget, 2)
# Group box to print results
results_group = QGroupBox("Analysis Results")
results_layout = QVBoxLayout()
self.results_text = QTextEdit()
self.results_text.setReadOnly(True)
results_layout.addWidget(self.results_text)
results_group.setLayout(results_layout)
self.layout.addWidget(results_group)
# Status bar for messages and errors
self.statusLabel = QLabel()
self.statusLabel.setText('Ready.')
self.layout.addWidget(self.statusLabel)
Code: Select all
from numpy import mean, std
from pandas import DataFrame
from scipy.stats import zscore
from scipy.signal import detrend
def analyze_cof_data(df: DataFrame):
"""
Performs detrending, outlier filtering, and calculates mean/stdev for CoF data.
Returns a dictionary of results and stats summary strings.
"""
STDEV_THRESHOLD = 1
time_values = df["Time"].to_numpy()
signal_data = df["CoF"].to_numpy()
detrended_signal = detrend(signal_data, type='linear')
abs_signal = abs(detrended_signal)
z_score = abs(zscore(abs_signal))
is_inlier = z_score < STDEV_THRESHOLD
points_kept = len(abs_signal[is_inlier])
avg_CoF = mean(abs_signal)
stdev_np = std(abs_signal, ddof=1)
results_summary = [
f"Original number of points: {len(signal_data)}",
f"Points kept after detrending and {STDEV_THRESHOLD} Standard Deviation filter: {points_kept}",
f"The average CoF is: {avg_CoF: .4f}",
f"The Standard Deviation is: {stdev_np: .4f}"
]
return {
'abs_signal': abs_signal,
'avg_CoF': avg_CoF,
'stdev_np': stdev_np,
'summary': results_summary
}
Vielen Dank im Voraus für jeden Rat!
1766431506
Anonymous
Ich arbeite an einem Projekt zur Entwicklung einer einfachen App, die auf einem Python-Skript zur Datenanalyse basiert, PyQt6 zum Formatieren der App und Nuitka zum Erstellen einer Exe-Datei verwende. (Ja, ich habe versucht, PyInstaller zu verwenden. Das Antivirenprogramm meines Unternehmens blockiert es ständig.) Die App ruft mit Pandas Daten aus einer CSV ab, transformiert die Daten mit SciPy und zeichnet die Daten dann mit MatPlotLib auf. Ich versuche, die Größe der Exe-Datei zu reduzieren, damit sie problemlos in meinem Labor geteilt werden kann. Irgendwelche Vorschläge, wie man die Importe reduzieren und die Größe der Exe-Datei reduzieren kann? Ich werde unten einige Auszüge einfügen: [code]from sys import argv, exit from PyQt6.QtWidgets import QApplication from gui_app import PyQtApp if __name__== "__main__": app = QApplication(argv) main_app_instance = PyQtApp() main_app_instance.show() try: exit(app.exec()) except SystemExit: print('Closing Window...') [/code] [code]import sys from os import path, getcwd from pandas import DataFrame, read_csv from PyQt6.QtWidgets import ( QWidget, QVBoxLayout, QHBoxLayout, QLabel, QLineEdit, QPushButton, QFileDialog, QTableView, QTextEdit, QGroupBox ) from PyQt6.QtGui import QIcon, QPixmap from data_model import PandasModel from data_analyzer import analyze_cof_data from graph_widget import MplGraphWidget def resource_path(relative_path): if hasattr(sys, "-MEIPASS"): return path.join(sys.MEIPASS, relative_path) return path.join(path.abspath("./images/"), relative_path) class PyQtApp(QWidget): # Defines main window def __init__(self): super().__init__() # Creates dataframe self.df = None # Window title self.title = 'RCP Analysis' # Window dimensions self.left = 0 self.top = 0 self.width = 600 self.height = 900 # Sets up main window self.setWindowTitle(self.title) self.setGeometry(self.left, self.top, self.width, self.height) self.layout = QVBoxLayout() self.setLayout(self.layout) # Displays widgets in init_ui self.init_ui() # Connects to file browser and searches for CSV files def getFileName(self): file_filter = 'Data File (*.csv)' filePath, _ = QFileDialog.getOpenFileName( parent=self, caption='Select a data file', directory=getcwd(), filter=file_filter ) if filePath: self.dataSourceField.setText(filePath) # Loads data from CSV into dataframe def retrieveDataset(self): # Defines path to source file self.urlSource = self.dataSourceField.text() if not self.urlSource or not path.exists(self.urlSource): self.statusLabel.setText("Invalid filepath provided or file does not exist.") return try: # Reads data from CSV self.df = read_csv( self.urlSource, header=6, usecols=[0,1], names=["Time", "CoF"] ) # Writes data into dataframe table if isinstance(self.df, DataFrame): self.df = self.df.dropna() self.model = PandasModel(self.df) self.table.setModel(self.model) self.statusLabel.setText(f"Successfully loaded {len(self.df)} rows.") self.table.horizontalHeader().setStretchLastSection(True) else: self.statusLabel.setText(f"Error: Loaded object is not a DataFrame (Type: {type(self.df)})") except Exception as e: self.statusLabel.setText(f"Erro loading file: {e}") print(f"Error details: {e}") # Begins data analysis def launchAnalysis(self): # Ensures data exists if self.df is not None and isinstance(self.df, DataFrame) and not self.df.empty: self.statusLabel.setText("Starting data analysis...") self.results_text.clear() try: # Runs analysis results = analyze_cof_data(self.df) # Writes results in results text box for line in results['summary']: self.results_text.append(line) # Graphs data in widget self.graph_widget.plot_data(self.df["Time"], self.df["CoF"], "Raw CoF Data Plot") # Success statement self.statusLabel.setText("Analysis complete.") print(f"Analyze complete. CoF: {results['avg_CoF']: .4f}, STDEV: {results['stdev_np']: .4f}") # Error statement except Exception as e: self.statusLabel.setText(f"Error during analysis: {e}") print(f"Error during analysis details: {e}") # Failure statement else: self.statusLabel.setText("Cannot analyze: No data loaded.") print("No data to analyze") # Sets up user interface def init_ui(self): # Icon icon = resource_path("QH_icon.ico") self.setWindowIcon(QIcon(icon)) # Logo logo = resource_path("QH_logo.png") pixmap = QPixmap(logo) logo_label = QLabel() logo_label.setPixmap(pixmap) self.layout.addWidget(logo_label) # Defines UI layout sourceLayout = QHBoxLayout() self.layout.addLayout(sourceLayout) # File browser widget label = QLabel('&Data Source:') self.dataSourceField = QLineEdit() label.setBuddy(self.dataSourceField) # Action buttons buttonBrowse = QPushButton('&Browse', clicked=self.getFileName) buttonRetrieve = QPushButton('&Get Data', clicked=self.retrieveDataset) buttonLaunch = QPushButton('&Analyze', clicked=self.launchAnalysis) # Organizes layout sourceLayout.addWidget(label) sourceLayout.addWidget(self.dataSourceField) sourceLayout.addWidget(buttonBrowse) sourceLayout.addWidget(buttonRetrieve) # Table widget and "Analyze" button self.table = QTableView() self.layout.addWidget(self.table, 1) self.layout.addWidget(buttonLaunch) # Graph widget self.graph_widget = MplGraphWidget(self) self.layout.addWidget(self.graph_widget, 2) # Group box to print results results_group = QGroupBox("Analysis Results") results_layout = QVBoxLayout() self.results_text = QTextEdit() self.results_text.setReadOnly(True) results_layout.addWidget(self.results_text) results_group.setLayout(results_layout) self.layout.addWidget(results_group) # Status bar for messages and errors self.statusLabel = QLabel() self.statusLabel.setText('Ready.') self.layout.addWidget(self.statusLabel) [/code] [code]from numpy import mean, std from pandas import DataFrame from scipy.stats import zscore from scipy.signal import detrend def analyze_cof_data(df: DataFrame): """ Performs detrending, outlier filtering, and calculates mean/stdev for CoF data. Returns a dictionary of results and stats summary strings. """ STDEV_THRESHOLD = 1 time_values = df["Time"].to_numpy() signal_data = df["CoF"].to_numpy() detrended_signal = detrend(signal_data, type='linear') abs_signal = abs(detrended_signal) z_score = abs(zscore(abs_signal)) is_inlier = z_score < STDEV_THRESHOLD points_kept = len(abs_signal[is_inlier]) avg_CoF = mean(abs_signal) stdev_np = std(abs_signal, ddof=1) results_summary = [ f"Original number of points: {len(signal_data)}", f"Points kept after detrending and {STDEV_THRESHOLD} Standard Deviation filter: {points_kept}", f"The average CoF is: {avg_CoF: .4f}", f"The Standard Deviation is: {stdev_np: .4f}" ] return { 'abs_signal': abs_signal, 'avg_CoF': avg_CoF, 'stdev_np': stdev_np, 'summary': results_summary } [/code] Vielen Dank im Voraus für jeden Rat!