Qt Widgets——主窗口及其主要组成部分

本文详细介绍了如何使用Qt框架构建传统的界面组件,包括主窗口、菜单、工具栏、悬浮部件、状态栏等,并通过实例展示了如何在代码中实现这些组件的功能。文章还提供了构建界面的主要步骤和关键类的解释,旨在帮助开发者更好地理解和应用Qt框架进行界面设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Main Window and Related Classes

QAction

动作类,用于当做一个菜单项或工具项插入菜单或工具栏

QActionGroup

动作组,用于管理多个动作,设置它们之间的互斥性等

QWidgetAction

部件动作,继承自QAction,用于将小部件插入菜单或工具栏

QDockWidget

悬浮部件,程序运行后可鼠标拖动的部件

QMainWindow

主窗口,是其它部件的容器

QMdiArea

子区域,加到QMainWindow中,用于放置多个QMdiSubWindow子窗口

QMdiSubWindow

子窗口

QMenu

菜单

QMenuBar

菜单栏,存放多个菜单

QSizeGrip

管理顶层窗口尺寸,一般位于软件的右下角,状态栏最右边,鼠标可拖动它改变窗口大小

QStatusBar

状态栏

QToolBar

工具栏

以QMainWindow为中心,构成了传统界面的各部分,现将它们拖在一起记录。

以rar压缩软件界面为例,各部分组成如下:

最上一行,叫菜单栏,由“文件”、“命令”等菜单组成,“选项”菜单已点击,弹出很多菜单项,Qt中用动作类QAction来表示菜单项。即QAction构成了菜单,菜单构成了菜单条,QAction可加入文字,图片等构成漂亮的菜单项。QDockWidget 悬浮部件较特殊,它在程序运行时,拖动可改变其位置。

——————————————————————————————————————————————————————————————————

建立步骤:

为了构建传统界面,需要在建立工程某步时选择继承类,如下图。

建成后,ui文件如下,“在这里输入”即是要求我们创建菜单,菜单栏下面一层即是默认的工具栏,没有添加动作,所以很细小(最左方有一个小点)

双击“在这里输入后”,可以写入文字,如下图,输入了创建了常用的“文件”。在下方五个按钮处的第一个新建一个动作,可以指定动作的名称,快捷键等,建完后,将它拖动到菜单或工具栏。

以下是效果图:

这时,只要将这个“动作”的“触发”信号连接到某个槽函数后,点击该菜单项或工具栏上的“新建”,就会执行槽函数。

以上就是建立一个传统界面的粗糙步骤

——————————————————————————————————————————————————————————————

QMainWindow

一个 主窗口各部分分布如图:

对比(图中中间白色大框为一个QTableWidget表格小部件):

公有函数分类如下:
QMainWindow(QWidget * parent = 0, Qt::WindowFlags flags = 0)  
    ~QMainWindow()  
//设置菜单部分  
void    setMenuBar(QMenuBar * menuBar)//带ui文件默认是有一个菜单条的,如果设置了这个之后,则默认的被覆盖,一个MainWindow只能有一个主菜单处于最上方  
void    setMenuWidget(QWidget * menuBar)//覆盖默认菜单,用一个自定义的部件代替菜单,甚至可以用一个按钮……,比较灵活,看不惯默认菜单的,可试试这个。  
  
//工具栏部分  
void    addToolBar(Qt::ToolBarArea area, QToolBar * toolbar)//添加一个工具条,用枚举值Qt::ToolBarArea(见1)设定停靠区域,由图可见,停靠区分为上下左右四区域。  
void    addToolBar(QToolBar * toolbar)//添加一个工具条(默认紧跟上一个工具条)  
QToolBar *  addToolBar(const QString & title)  
void    addToolBarBreak(Qt::ToolBarArea area = Qt::TopToolBarArea)//添加一个Break(破裂; 间断; 或译为区域),这时,新添加的工具条将不再紧跟前一个工具条,而是另起一行。  
void    insertToolBar(QToolBar * before, QToolBar * toolbar)//在before工具条后加一个  
void    insertToolBarBreak(QToolBar * before)//添加分隔线  
void    removeToolBar(QToolBar * toolbar)  
void    removeToolBarBreak(QToolBar * before)  
void    setToolButtonStyle(Qt::ToolButtonStyle toolButtonStyle)//设置工具条上显示模式,默认只有文件,可设置成图片或文字形式(见2)  
void setIconSize(const QSize & iconSize)//设置工具条上图标大小,在上一个函数设置图标模式后有效  
  
//可停靠窗口部件  
void addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget)//area枚举值见3  
void addDockWidget(Qt::DockWidgetArea area, QDockWidget * dockwidget, Qt::Orientation orientation)  
void removeDockWidget(QDockWidget * dockwidget)  
void setCorner(Qt::Corner corner, Qt::DockWidgetArea area)//让四个角落(corner)中一个区域"归属于"某个区域(area),具体看最下方例子  
void setDockOptions(DockOptions options)//设置停靠选项,比如允许动画或是否允许拖放重合成一个tab选项卡类型的部件,枚举值见4  
void setTabPosition(Qt::DockWidgetAreas areas, QTabWidget::TabPosition tabPosition)//设置形成的tab位置  
void setTabShape(QTabWidget::TabShape tabShape)  
void setDocumentMode(bool enabled)  
void splitDockWidget(QDockWidget * first, QDockWidget * second, Qt::Orientation orientation)//部件拖动至处于同一区域时,默认重合形成tab,利用这个,可将它们分开  
  
//设置中间部件  
void setCentralWidget(QWidget * widget)  
QWidget * centralWidget() const  
  
//添加状态栏  
void setStatusBar(QStatusBar * statusbar)  
  
//保存窗口形状信息  
bool restoreState(const QByteArray & state, int version = 0)  
<p>QByteArray saveState(int version = 0) const  
bool restoreDockWidget(QDockWidget * dockwidget)  
  
</p>//其它  
Qt::DockWidgetArea  corner(Qt::Corner corner) const  
virtual QMenu * createPopupMenu()  
DockOptions dockOptions() const  
Qt::DockWidgetArea  dockWidgetArea(QDockWidget * dockwidget) const  
bool    documentMode() const  
QSize   iconSize() const  
bool    isAnimated() const  
bool    isDockNestingEnabled() const  
QMenuBar *  menuBar() const  
QWidget *   menuWidget() const  
QStatusBar *    statusBar() const  
QTabWidget::TabPosition tabPosition(Qt::DockWidgetArea area) const  
QTabWidget::TabShape    tabShape() const  
QList<QDockWidget *>  tabifiedDockWidgets(QDockWidget * dockwidget) const  
void    tabifyDockWidget(QDockWidget * first, QDockWidget * second)  
QWidget *   takeCentralWidget()  
Qt::ToolBarArea toolBarArea(QToolBar * toolbar) const  
bool    toolBarBreak(QToolBar * toolbar) const  
Qt::ToolButtonStyle toolButtonStyle() const  

1,enum Qt::ToolBarArea

ConstantValue
Qt::LeftToolBarArea0x1
Qt::RightToolBarArea0x2
Qt::TopToolBarArea0x4
Qt::BottomToolBarArea0x8
Qt::AllToolBarAreasToolBarArea_Mask
Qt::NoToolBarArea0

2,enum Qt::ToolButtonStyle

ConstantValueDescription
Qt::ToolButtonIconOnly0只显示图标
Qt::ToolButtonTextOnly1Only display the text.
Qt::ToolButtonTextBesideIcon2The text appears beside the icon.
Qt::ToolButtonTextUnderIcon3文本显示在图标下方
Qt::ToolButtonFollowStyle4Follow the style.

3,enum Qt::DockWidgetArea
flags Qt::DockWidgetAreas

ConstantValue
Qt::LeftDockWidgetArea0x1
Qt::RightDockWidgetArea0x2
Qt::TopDockWidgetArea0x4
Qt::BottomDockWidgetArea0x8
Qt::AllDockWidgetAreasDockWidgetArea_Mask
Qt::NoDockWidgetArea0

4,enum QMainWindow::DockOption
flags QMainWindow::DockOptions

ConstantValueDescription
QMainWindow::AnimatedDocks0x01animated相同
QMainWindow::AllowNestedDocks0x02dockNestingEnabled相同
QMainWindow::AllowTabbedDocks0x04允许形成下方有tapBar的重合部件
QMainWindow::ForceTabbedDocks0x08Each dock area contains a single stack of tabbed dock widgets. In other words, dock widgets cannot be placed next to each other in a dock area. If this option is set, AllowNestedDocks has no effect.
QMainWindow::VerticalTabs0x10设置tabBar在竖直左方位置(默认在下方)

以rar压缩软件为例,用代码写出界面主要部分:

以下代码只是用于理解,是很不合理的。主要测试各部分小部件的位置,外观等,以及mainwidow的形状配置保存

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QAction>
#include <QMenu>
#include <QIcon>
#include <QSize>
#include <QLabel>
#include <QDockWidget>
#include <QTableWidget>
#include <QSettings>

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

    //菜单栏部分
    QMenu *menu1=ui->menuBar->addMenu("文件(&F)");
    QAction *me1_act1=menu1->addAction("打开压缩文件(O)");
    me1_act1->setShortcut(QKeySequence(tr("Ctrl+O")));
    //connect(me1_act1,SIGNAL(triggered()),……
    QAction *me1_act2=menu1->addAction("保存压缩文件副本为(V)");
    me1_act2->setIcon(QIcon("://img/sava.ico"));
    menu1->addSeparator();
    QAction *me1_act3=menu1->addAction("退出(X)");
    connect(me1_act3,SIGNAL(triggered()),this,SLOT(close()));
    ui->menuBar->addMenu("命令(&C)");

    //"文件"菜单部分
    QAction *tb1_act1=ui->mainToolBar->addAction(QIcon("://img/tool1.ico"),"添加");
    ui->mainToolBar->addSeparator();
    QAction *tb1_act2=ui->mainToolBar->addAction(QIcon("://img/tool2.ico"),"解压到");
    setToolButtonStyle(Qt::ToolButtonTextUnderIcon);
    setIconSize(QSize(50,50));

    addToolBarBreak();
    toolBar=new QToolBar;
    toolBar->setObjectName("tb2");//设置对象名,用于保存配置
    toolBar->setToolButtonStyle(Qt::ToolButtonIconOnly);
    toolBar->setIconSize(QSize(20,20));
    addToolBar(toolBar);
    QAction *tb2_act1=toolBar->addAction(QIcon("://img/sharp.ico"),"");

    //添加中间主部件
    QTableWidget *tb1=new QTableWidget;
    setCentralWidget(tb1);

    //添加悬浮部件
    QDockWidget *dock1= new QDockWidget("上侧部件");
    addDockWidget(Qt::TopDockWidgetArea,dock1);
    QDockWidget *dock2_1= new QDockWidget("左侧部件1");
    addDockWidget(Qt::LeftDockWidgetArea,dock2_1);
    QDockWidget *dock2_2= new QDockWidget("左侧部件2");
    addDockWidget(Qt::LeftDockWidgetArea,dock2_2);
    splitDockWidget(dock2_1,dock2_2,Qt::Horizontal);
    QDockWidget *dock3= new QDockWidget("右侧部件");
    dock3->setFeatures(QDockWidget::DockWidgetVerticalTitleBar|QDockWidget::DockWidgetMovable);
    addDockWidget(Qt::RightDockWidgetArea,dock3);
    QDockWidget *dock4= new QDockWidget("下侧部件");
    addDockWidget(Qt::BottomDockWidgetArea,dock4);
    //setCorner(Qt::BottomLeftCorner,Qt::LeftDockWidgetArea);//让左下角区域归于左边停靠区域
    dock1->setObjectName("dock1");
    dock2_1->setObjectName("dock2_1");
    dock2_2->setObjectName("dock2_2");
    dock3->setObjectName("dock3");
    dock4->setObjectName("dock4");

    //状态栏部分
    QLabel *lbl1=new QLabel("无状态");
    ui->statusBar->addWidget(lbl1);

    //读取窗口及部件形状与状态
    readSettings();

}
void MainWindow::closeEvent(QCloseEvent *event)
{
    QSettings settings("大中华有限公司", "测试软件名");
    settings.setValue("geometry", saveGeometry());
    settings.setValue("windowState", saveState());
    settings.sync();
}
void MainWindow::readSettings()
{
    QSettings settings("大中华有限公司", "测试软件名");
    restoreGeometry(settings.value("geometry").toByteArray());
    restoreState(settings.value("windowState").toByteArray());
}


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

  

### QT人脸识别UI设计与实现教程 #### 1. 软件架构概述 基于QT的人脸识别系统通常由部分组成:前端UI界面和后端逻辑处理。其中,前端负责展示交互界面并接收用户输入;后端则利用OpenCV或其他机器学习框架完成图像采集、预处理、特征提取及匹配等功能[^1]。 #### 2. UI界面设计 在QT中可以借助`Qt Designer`工具快速构建图形化用户界面。以下是具体的设计要点: - **主窗口布局** 使用`QMainWindow`作为主容器,在其基础上添加多个子控件来满足不同功能需求。例如,可以通过拖拽方式放置按钮(`QPushButton`)用于触发人脸检测或录入操作,同时嵌入标签组件(`.QLabel`)显示实时摄像头画面或者提示信息[^3]。 - **常用控件说明** - `QPushButton`: 提供点击事件响应机制,适合用来启动特定流程如“开始录制视频流”、“保存当前帧至数据库”等。 - `QLabel`: 显示静态图片或动态更新的内容比如捕捉到的脸部区域截图。 - `QLineEdit/QTextEdit`: 输入框允许管理员填写备注资料关联每张注册照片的身份属性。 ```python def setup_ui(self, main_window): self.central_widget = QtWidgets.QWidget(main_window) # 创建一个水平布局管理器 layout = QtWidgets.QHBoxLayout() # 添加左侧的 QLabel 来显示相机视图 self.camera_label = QtWidgets.QLabel() self.camera_label.setText("Camera View") self.camera_label.setFixedSize(640, 480) # 设置固定大小以适应常见分辨率 layout.addWidget(self.camera_label) # 右侧控制面板 control_panel_layout = QtWidgets.QVBoxLayout() self.start_button = QtWidgets.QPushButton('Start Camera') self.start_button.clicked.connect(self.start_camera_feed) control_panel_layout.addWidget(self.start_button) self.capture_button = QtWidgets.QPushButton('Capture Face') self.capture_button.setEnabled(False) # 初始状态不可用直到摄像机开启 self.capture_button.clicked.connect(self.capture_face_image) control_panel_layout.addWidget(self.capture_button) layout.addLayout(control_panel_layout) self.central_widget.setLayout(layout) main_window.setCentralWidget(self.central_widget) ``` #### 3. 后台逻辑集成 为了使整个应用流畅运行,需将计算机视觉库引入项目以便执行核心算法任务。这里推荐采用开源强大的 OpenCV 库来进行图像分析工作[^3]。 ##### 关键函数解析 - `initMainWindow()` 初始化所有必要的成员变量并将它们绑定到对应的 GUI 控件上; - `imgProc()` 执行实际的数据转换过程——即将来自设备传感器获取原始像素数组转化为可供后续阶段使用的标准格式对象 (Mat); - `on_detectPushButton_clicked()` 定义了当按下某个指定按键后的回调行为模式. 另外值得注意的是,由于涉及到异步 I/O 操作(像读取网络摄像头源),因此可能还需要考虑线程同步问题以免造成资源竞争条件引发崩溃风险[^2]. #### 结论 综上所述,通过合理规划应用程序结构,并充分利用现代 C++ 特性和第三方类库的优势,完全可以打造出既美观又实用的人脸验证解决方案。当然这仅仅是一个基础版本示范而已,针对更复杂场景下的定制开发还需进一步深入研究探索更多可能性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值