如何在PyQt对话框中同步显示控制台文本输出与生成的图表?
Solution to Display Console Outputs in PyQt Window
Hey there! I see you want to move those console-based result explanations into your PyQt dialog alongside the chart. Let's modify your code to add a text panel that captures and displays all those print statements, plus we'll fix a tiny bug in your counting logic along the way.
Step-by-Step Modifications:
- Add a Text Display Widget: We'll use
QTextEditto create a read-only panel for showing results clearly. - Redirect Console Output: Build a custom stream handler to route
print()calls directly to theQTextEditwidget. - Fix Counting Bug: Your
count4condition was usingmodelSVM.predict(i)(which would throw an error) — we'll correct that to check ifi ==4. - Update Deprecated Code: Replace the old
cross_validationmodule with the currentmodel_selectionfrom scikit-learn.
Modified Full Code:
import sys import io from PyQt5.QtWidgets import QDialog, QApplication, QPushButton, QVBoxLayout, QTextEdit from numpy import genfromtxt import numpy as np import matplotlib matplotlib.use('Agg') import matplotlib.pyplot as plt from sklearn.svm import LinearSVC, SVC from sklearn.decomposition import PCA from itertools import cycle from sklearn.model_selection import train_test_split, StratifiedKFold from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar # Custom stream to redirect print output to QTextEdit class ConsoleStream(io.StringIO): def __init__(self, text_edit): super().__init__() self.text_edit = text_edit def write(self, text): super().write(text) # Append text to the widget and auto-scroll to bottom self.text_edit.append(text.strip()) self.text_edit.verticalScrollBar().setValue(self.text_edit.verticalScrollBar().maximum()) def flush(self): # Required for stream compatibility with print() pass class Window(QDialog): def __init__(self, parent=None): super(Window, self).__init__(parent) self.setWindowTitle("Heart Disease Prediction Results") self.resize(1000, 700) # Plot setup self.figure = plt.figure() self.canvas = FigureCanvas(self.figure) self.toolbar = NavigationToolbar(self.canvas, self) # Action button self.button = QPushButton('Run Prediction & Plot') self.button.clicked.connect(self.my_model) # Results text panel self.result_text = QTextEdit() self.result_text.setReadOnly(True) self.result_text.setPlaceholderText("Prediction results will appear here...") # Redirect console output to the text panel self.console_stream = ConsoleStream(self.result_text) sys.stdout = self.console_stream # Layout arrangement layout = QVBoxLayout() layout.addWidget(self.toolbar) layout.addWidget(self.canvas) layout.addWidget(self.button) layout.addWidget(self.result_text) self.setLayout(layout) def plot_2D(self, data, target, target_names, ax): colors = cycle('rgbcmykw') target_ids = range(len(target_names)) for i, c, label in zip(target_ids, colors, target_names): ax.scatter(data[target == i, 0], data[target == i, 1], c=c, label=label) ax.legend() self.canvas.draw() def my_model(self): # Clear previous content self.result_text.clear() ax = self.figure.add_subplot(111) ax.clear() # Load and prepare data dataset = genfromtxt('cleveland_data.csv', dtype=float, delimiter=',') X = dataset[:, 0:12] y = dataset[:, 13] # Apply PCA pca = PCA(n_components=5, whiten=True).fit(X) X_new = pca.transform(X) # Generate plot target_names = ['Class 0', 'Class 1', 'Class 2', 'Class 3', 'Class 4'] self.plot_2D(X_new, y, target_names, ax) # Linear SVM Evaluation print("=== Linear SVM (Train-Test Split) ===") modelSVM = LinearSVC(C=0.001) X_train, X_test, y_train, y_test = train_test_split(X_new, y, test_size=0.4, train_size=0.6, random_state=0) modelSVM.fit(X_train, y_train) score = modelSVM.score(X_test, y_test) print(f"Test Accuracy: {score:.4f}") # Prediction class distribution print("\n=== Prediction Class Distribution ===") count0 = count1 = count2 = count3 = count4 = 0 for pred in modelSVM.predict(X_new): if pred == 0: count0 +=1 elif pred ==1: count1 +=1 elif pred ==2: count2 +=1 elif pred ==3: count3 +=1 elif pred ==4: count4 +=1 total = count0 + count1 + count2 + count3 + count4 print(f"Class 0: {count0} ({count0/total:.2%})") print(f"Class 1: {count1} ({count1/total:.2%})") print(f"Class 2: {count2} ({count2/total:.2%})") print(f"Class 3: {count3} ({count3/total:.2%})") print(f"Class 4: {count4} ({count4/total:.2%})") # RBF SVM Evaluation print("\n=== RBF SVM (Train-Test Split) ===") modelSVM2 = SVC(C=0.001, kernel='rbf') X_train1, X_test1, y_train1, y_test1 = train_test_split(X_new, y, test_size=0.4, train_size=0.6, random_state=0) modelSVM2.fit(X_train1, y_train1) score2 = modelSVM2.score(X_test1, y_test1) print(f"Test Accuracy: {score2:.4f}") # Stratified K-Fold Cross Validation print("\n=== RBF SVM (Stratified 5-Fold Cross Validation) ===") skf = StratifiedKFold(n_splits=5, shuffle=True, random_state=0) fold_scores = [] for fold_idx, (train_index, test_index) in enumerate(skf.split(X, y), 1): X_train3, X_test3 = X[train_index], X[test_index] y_train3, y_test3 = y[train_index], y[test_index] modelSVM3 = SVC(C=0.001, kernel='rbf') modelSVM3.fit(X_train3, y_train3) fold_score = modelSVM3.score(X_test3, y_test3) fold_scores.append(fold_score) print(f"Fold {fold_idx} Accuracy: {fold_score:.4f}") print(f"\nMean Cross-Validation Accuracy: {np.mean(fold_scores):.4f}") if __name__ == '__main__': app = QApplication(sys.argv) main = Window() main.show() sys.exit(app.exec_())
Key Changes Explained:
- Console Redirection: The
ConsoleStreamclass captures everyprint()output and appends it to the text panel, with auto-scrolling so you always see the latest results. - Improved Readability: Added section headers, percentage distributions, and rounded accuracy scores to make results easier to interpret.
- Bug Fix: Corrected the
count4logic to avoid runtime errors. - Modernized Imports: Switched to the supported
model_selectionmodule instead of the deprecatedcross_validation.
Now when you click the button, both the PCA plot and all model evaluation results will display in the same window—no more switching back to the console!
内容的提问来源于stack exchange,提问作者Kat
相关产品推荐
相关产品推荐

