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

数独应用开发:如何在不改变现有布局的前提下添加/修改QStackedLayout?

数独应用布局问题:实现文本框与数独网格叠加显示

我正在开发一款数独应用,想要让文本框(Line Edit)显示在数独网格的上方。目前我用了一个包含两页的QStackedWidget:一页放数独网格,另一页放文本框。窗口缩放时布局能正常适配,但尝试添加QStackedLayout并启用ShowAll模式后,整个窗口布局完全乱掉,也没实现预期的叠加显示效果。

两张布局截图的唯一区别就是这段代码:

QStackedLayout * layoutt = new QStackedLayout;
layoutt->addWidget(ui->stackedWidget);
layoutt->setStackingMode(QStackedLayout::StackingMode::StackAll);

第三张图显示了我认为在把stackedWidget分配给新布局后被破坏的结构。

我发现Qt Designer里没法直接添加QStackedLayout,也不确定怎么把现有布局里的stackedWidget替换成以它为子项的QStackedLayout。

我的最终目标是让数独网格和文本框页面同时可见,我觉得这需要用QStackedLayout——也就是用QStackedLayout替换现有stackedWidget的位置,再把stackedWidget设为它的子项。


补充代码状态

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QStackedLayout>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    // 同时显示数独图片(第2页)和文本框(第1页)
    ((QStackedLayout *)ui->stackedWidget->layout())->setStackingMode(QStackedLayout::StackAll);
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp

#include "mainwindow.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    // 初始化应用
    QApplication a(argc, argv);

    // 读取样式表(如果存在)
    QString styles = readTextFile(":/styles.css");
    if(styles.length() > 0)
    {
        a.setStyleSheet(styles);
    }

    MainWindow w;
    w.setWindowTitle("Sudoku Solver");
 
    w.show();
    return a.exec();
}

表单布局截图

表单布局截图1
表单布局截图2


样式表(供参考)

QPushButton#SolveButton
{
image: url(:/Resources/pushbutton.png);
color: rgb(255, 255, 255);
}

QPushButton#SolveButton:pressed
{
image: url(:/Resources/pushbutton_pressed.png);
color: rgb(200, 200, 200);
}

QPushButton#SolveButton:hover
{
border: none;
background-color: rgb(255, 255, 255);
padding: 2px;
}

QPushButton#HelpButton
{
image: url(:/Resources/Blue_question_mark_icon.svg.png);
}

QPushButton#HelpButton:pressed
{
image: url(:/Resources/Blue_question_mark_icon_pressed.png);
}

QPushButton#HelpButton:hover
{
border-radius: 30px;
}

QPushButton#TabButton
{
image: url(:/Resources/active.png);
color: rgb(0, 0, 0);
border: none;
}

QLabel#SudokuGrid
{
    image: url(:/Resources/blank-sudoku-grid.png);
}

解决方案

你不需要额外套一层QStackedLayout,QStackedWidget本身内部就是QStackedLayout,直接修改它的堆叠模式就能实现叠加显示,以下是关键调整步骤:

  1. 安全设置堆叠模式
    你的补充代码里已经尝试修改内部布局,但用static_cast存在类型转换风险,换成qobject_cast更安全,避免运行时崩溃:

    if (auto stackedLayout = qobject_cast<QStackedLayout*>(ui->stackedWidget->layout())) {
        stackedLayout->setStackingMode(QStackedLayout::StackAll);
    }
    
  2. 确保叠加页面适配
    要让两个页面缩放时对齐且不遮挡,需注意:

    • 数独网格页面:将QLabel#SudokuGrid的scaledContents属性设为true,并把它放在一个占满页面的布局里,确保图片跟随窗口缩放
    • 文本框页面:把所有Line Edit放在网格布局中,与数独网格的格子一一对应,同时将页面的背景设为透明,避免盖住下方的网格:
      ui->textBoxPage->setAttribute(Qt::WA_TranslucentBackground);
      
  3. 如果非要替换为QStackedLayout
    其实QStackedWidget就是QStackedLayout的封装容器,没必要替换,但如果确实需要,步骤如下:

    • 在Qt Designer中删除现有stackedWidget,给中央控件(centralWidget)添加一个临时布局(比如QVBoxLayout)
    • 在代码中替换为QStackedLayout并添加原页面:
      auto central = ui->centralWidget;
      delete central->layout(); // 移除临时布局
      auto stackedLayout = new QStackedLayout(central);
      // 假设你已经把原stackedWidget的两个页面保存为textBoxPage和gridPage
      stackedLayout->addWidget(textBoxPage);
      stackedLayout->addWidget(gridPage);
      stackedLayout->setStackingMode(QStackedLayout::StackAll);
      
  4. 避坑提示

    • 不要给叠加的Widget设置固定大小,否则窗口缩放时会错位
    • 确保文本框的大小和位置与数独网格的格子精准对齐,可以通过布局的间距、拉伸因子调整

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 06:55:53