You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PyQt5中QWidget无法在QMainWindow显示,需单窗口内打开子部件

Fixing QWidget Not Displaying in QMainWindow (Same-Window Interface Switching)

Got it, let's tackle this problem. The root issue here is that you're likely creating a new QWidget and calling show() on it when clicking that blue area—which is why a separate window pops up instead of loading inside your main window. QMainWindow relies on its central widget to hold the main content, so we need to manage content switching through that.

The best approach here is to use a QStackedWidget as your main window's central widget. This widget acts like a container for multiple pages, letting you switch between them without opening new windows. Here's a step-by-step solution with example code:

Step 1: Define Your Page Widgets

First, create separate QWidget subclasses for each of your interfaces: your home page, the "View/Edit Processed Slices" page (your Figure 1), and the target page you want to load (your Figure 2).

from PyQt5.QtWidgets import (
    QMainWindow, QWidget, QStackedWidget, QVBoxLayout,
    QMenuBar, QMenu, QAction, QLabel, QPushButton, QFrame
)
from PyQt5.QtGui import QColor
from PyQt5.QtCore import pyqtSignal

class HomePage(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        layout.addWidget(QLabel("This is your main home page"))
        self.setLayout(layout)

class ProcessedSlicesPage(QWidget):
    # Define a custom signal to notify main window to switch pages
    switch_to_target = pyqtSignal()

    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        
        # Your "blue rectangle" area (simulated with a styled button here)
        blue_area = QPushButton("Click this blue area")
        blue_area.setStyleSheet("background-color: #4287f5; color: white; padding: 20px;")
        blue_area.clicked.connect(self.switch_to_target.emit)  # Emit signal on click
        
        layout.addWidget(QLabel("View/Edit Processed Slices (Figure 1)"))
        layout.addWidget(blue_area)
        self.setLayout(layout)

class TargetPage(QWidget):
    def __init__(self):
        super().__init__()
        layout = QVBoxLayout()
        layout.addWidget(QLabel("This is your target page (Figure 2)"))
        self.setLayout(layout)

Step 2: Set Up Main Window with QStackedWidget

In your main window class, set QStackedWidget as the central widget, add all your page widgets to it, and connect menu actions and page signals to switch between pages.

class MainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setWindowTitle("Single Window Interface")
        self.setGeometry(100, 100, 800, 600)

        # Create stacked widget as central widget
        self.stacked_widget = QStackedWidget()
        self.setCentralWidget(self.stacked_widget)

        # Add all pages to stacked widget
        self.home_page = HomePage()
        self.slices_page = ProcessedSlicesPage()
        self.target_page = TargetPage()

        self.stacked_widget.addWidget(self.home_page)
        self.stacked_widget.addWidget(self.slices_page)
        self.stacked_widget.addWidget(self.target_page)

        # Set initial page to home
        self.stacked_widget.setCurrentWidget(self.home_page)

        # Create menu bar
        self._create_menu_bar()

        # Connect the slices page's signal to switch to target page
        self.slices_page.switch_to_target.connect(self._show_target_page)

    def _create_menu_bar(self):
        menu_bar = self.menuBar()
        view_edit_menu = menu_bar.addMenu("View/Edit")
        
        # Add action for "View/Edit Processed Slices"
        view_slices_action = QAction("View/Edit Processed Slices", self)
        view_slices_action.triggered.connect(self._show_slices_page)
        view_edit_menu.addAction(view_slices_action)

    def _show_slices_page(self):
        # Switch to the processed slices page
        self.stacked_widget.setCurrentWidget(self.slices_page)

    def _show_target_page(self):
        # Switch to the target page (Figure 2)
        self.stacked_widget.setCurrentWidget(self.target_page)

Step 3: Run the Application

Finally, set up and run your app:

if __name__ == "__main__":
    import sys
    from PyQt5.QtWidgets import QApplication

    app = QApplication(sys.argv)
    window = MainWindow()
    window.show()
    sys.exit(app.exec_())

Key Notes to Remember

  • Never call show() on a new QWidget if you want it inside the main window—this creates a separate top-level window.
  • QStackedWidget is perfect for this use case: it holds multiple widgets but only displays one at a time. You can switch between them using either setCurrentIndex() or setCurrentWidget().
  • Use custom signals (like switch_to_target in the example) to let child pages communicate with the main window. This keeps your code clean and decoupled.

With this setup, clicking the menu will load the Processed Slices page in your main window, and clicking the blue area will switch directly to your target page—all without opening any new windows.

内容的提问来源于stack exchange,提问作者Migui Mag

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:01:26