QT ④ 布局&MainWindow

一、布局管理

一个界面只能有一个布局

1. 水平布局(QHBoxLayout)

  • 特点:控件按水平方向从左到右排列。

  • 适用场景:需要横向排列的控件(如工具栏按钮、一行内的输入框和按钮)。

  • 示例

    QHBoxLayout *hLayout = new QHBoxLayout;
    hLayout->addWidget(button1); // 左侧
    hLayout->addWidget(button2); // 中间
    hLayout->addWidget(button3); // 右侧
    

2. 垂直布局(QVBoxLayout)

  • 特点:控件按垂直方向从上到下排列。

  • 适用场景:需要纵向排列的控件(如表单中的多行输入框、垂直排列的按钮组)。

  • 示例

    QVBoxLayout *vLayout = new QVBoxLayout;
    vLayout->addWidget(label1);  // 上方
    vLayout->addWidget(input1);  // 中间
    vLayout->addWidget(button);  // 下方
    

3. 网格布局(QGridLayout)

  • 特点:控件按行列网格形式排列,类似表格,可指定控件占据的行数和列数。

  • 适用场景:需要精确控制行列位置的布局(如计算器按钮、复杂表单)。

  • 示例

    QGridLayout *gridLayout = new QGridLayout;
    gridLayout->addWidget(btn1, 0, 0); // 第0行第0列
    gridLayout->addWidget(btn2, 0, 1); // 第0行第1列
    gridLayout->addWidget(btn3, 1, 0, 1, 2); // 第1行第0列,跨2列
    

共性与优势

  • 自动适应窗口大小变化,无需手动计算控件位置。
  • 可嵌套使用(如水平布局中包含垂直布局),构建复杂界面。
  • 通过 addStretch() 可添加伸缩项,控制控件间距和对齐方式。

二、主窗口 QMainWindow

主要布局区域

  1. 菜单栏(Menu Bar)
    • 位于窗口顶部,通过 menuBar() 获取,用于添加下拉菜单(QMenu)。
    • 示例:QMenu *fileMenu = menuBar()->addMenu("文件");
  2. 工具栏(Tool Bar)
    • 通常在菜单栏下方,可浮动或停靠,通过 addToolBar() 添加,用于放置常用工具按钮(QAction)。
    • 示例:QToolBar *toolBar = addToolBar("工具");
  3. 中央部件(Central Widget)
    • 窗口的核心区域,所有主要内容(如文本编辑、表格等)都放在这里,必须设置(否则窗口会空白)。
    • 示例:setCentralWidget(new QTextEdit);(将文本编辑框设为中央部件)
  4. 状态栏(Status Bar)
    • 位于窗口底部,通过 statusBar() 获取,用于显示临时状态信息或永久提示。
    • 示例:statusBar()->showMessage("就绪");
  5. dock 窗口(Dock Widget)
    • 可停靠在窗口边缘(上下左右)的浮动面板,通过 addDockWidget() 添加,用于放置辅助功能(如工具栏、属性面板)。
    • 示例:addDockWidget(Qt::RightDockWidgetArea, new QDockWidget("属性"));
#include "mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    resize(640,480);

    //menuBar() 获取默认的菜单栏    addMenu() 添加菜单,返回QMenu首地址
    QMenu *fileMenu = menuBar()->addMenu("文件");
    //QAction *act = menuBar()->addMenu(new QMenu("编辑"));
    QAction *newAct = new QAction("新建");
    newAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_N));
    //newAct->setIcon(QIcon(""));
    newAct->setStatusTip("新建...");
    fileMenu->addAction(newAct);            //添加菜单项
    connect(newAct , &QAction::triggered , [&](){
        qDebug() << "新建";
    });


    QAction *openAct = fileMenu->addAction("打开");
    openAct->setShortcut(QKeySequence(Qt::CTRL | Qt::Key_O));
    openAct->setStatusTip("打开...");
    connect(openAct , &QAction::triggered , this , &MainWindow::openFunc);

    QAction *saveAct = fileMenu->addAction("保存",QKeySequence(Qt::CTRL | Qt::Key_S),[&](){
        qDebug() << "保存";
    });
    saveAct->setStatusTip("保存...");
//============================================子菜单=================================

    fileMenu->addSeparator();   //添加分割线

    QMenu *subMenu = fileMenu->addMenu("最近打开的文件");
    subMenu->addAction("1.cpp");
    subMenu->addAction("2_main.cpp");

//===========================工具栏================================
    QToolBar *tool_1 = addToolBar("文件");
    tool_1->addAction(newAct);
    tool_1->addAction(openAct);
    tool_1->addAction(saveAct);
    tool_1->setMovable(false);  //设置工具栏不可移动
    //tool_1->setAllowedAreas(Qt::TopToolBarArea | Qt::BottomToolBarArea);  //设置工具栏可移动区域

    QToolBar *tool_2 = new QToolBar("工具");
    tool_2->setMovable(false);
    tool_2->addWidget(new QLabel("页码"));
    tool_2->addWidget(new QLineEdit);
    tool_2->addWidget(new QPushButton("跳转"));
    addToolBar(Qt::BottomToolBarArea,tool_2);

//===========================状态栏============================

    //显示状态栏  第二个参数 timeout = 0 表示一直显示 , timeout单位毫秒;
    //statusBar()->showMessage("记事本",5000);
     QStatusBar *sb = statusBar();
    QLabel *lb = new QLabel("1111");
    lb->setMinimumWidth(200);
    sb->addWidget(lb);
    sb->addWidget(new QLabel("xxxxxxxx"));
    QPushButton *btn = new QPushButton;
    QMenu *m = new QMenu;
    m->addAction(newAct);
    m->addAction(openAct);
    m->addAction(saveAct);
    btn->setMenu(m);

    sb->addWidget(btn);


//===================================工作区=====================================
    QListWidget *lw = new QListWidget;
    QStringList list = {"1_homework","2_QLayout","3_QMainWindow"};
    lw->addItems(list);

    QDockWidget *dw = new QDockWidget("项目");            //构造工作区
    dw->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);//设置允许区域
    dw->setMaximumWidth(100);
    dw->setWidget(lw);
    addDockWidget(Qt::LeftDockWidgetArea,dw);       //添加工作区到当前界面的某个区域

    QDockWidget *dw2 = new QDockWidget("工作区");            //构造工作区
    dw2->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea);//设置允许区域
    dw2->setMaximumWidth(100);
    dw2->setWidget(new QCalendarWidget);        //设置日历
    addDockWidget(Qt::RightDockWidgetArea,dw2);

    this->tabifyDockWidget(dw,dw2);             //工作区堆叠

//==================================中央控件==================================

    //选项卡
    QTabWidget *tab = new QTabWidget;
    tab->addTab(new QTextEdit,"tab 1"); //添加选项卡
    tab->addTab(new QTextEdit,"tab 2");
    tab->insertTab(0,new QTextEdit,"insert tab");    //在0位置处插入一个选项卡
    tab->setTabsClosable(true);         //设置选项卡可关闭(功能需自己实现)
    this->setCentralWidget(tab);        //设置为中央控件


}

MainWindow::~MainWindow()
{

}

void MainWindow::openFunc()
{
    qDebug() << "打开";
}

运行截图:

alt