目录
- 主界面需要有什么?
- 然后要做什么?添加两个主菜单(声明)
- 下一步应该干什么?能够跳转到文件
-
- 有哪几个动作?
- 动作如何声明?
- 既然有动作,那肯定会涉及到信号与槽函数
- QWidget这个基类用来做什么的?
- [class Widget : public QMainWindow这边为什么把基类给改了](#class Widget : public QMainWindow这边为什么把基类给改了)
- [Stacked Widget控件](#Stacked Widget控件)
- 创建菜单栏函数
主界面需要有什么?
一个堆栈,用来切换页面的。
一个标签,用于标题
一个工具箱,用于按键功能实现
一个列表控件,用于显示信息
然后是需要有主菜单来实现堆栈的页面切换
上方的两个小按钮(销售菜单和修改密码),下面有一一行二列的布局。
这个是最终版
然后要做什么?添加两个主菜单(声明)
QMenu
- 名字太low了
销售管理用manageMenu
修改密码用passwordMenu - 要带*号,QMenu manageMenu;在一个QT的头文件中,这个 号有什么意义?
在Qt的头文件中,QMenu *manageMenu;
这段代码中的*
号是C++中的指针符号,它的作用是定义一个指向QMenu
类型对象的指针。
具体解释如下:
QMenu
是Qt库中的一个类,代表一个菜单对象。*
表示这是一个指向QMenu
对象的指针,而不是直接的QMenu
对象。manageMenu
是这个指针的变量名。
因此,这行代码的意思是:声明了一个名为manageMenu
的指针,它指向一个QMenu
类型的对象。在实际代码中,manageMenu
可以指向一个已经创建的QMenu
对象,或者通过动态分配内存(比如new QMenu()
)来创建这个对象。
下一步应该干什么?能够跳转到文件
需要定义动作Action,只有定义了Action才能实现跳转
有哪几个动作?
销售管理还有修改密码需要进行跳转
跳转到两个小界面,然后还有一个退出
动作如何声明?
QAction click1
- 名字low
- 用指针来声明,加*号
为什么用选择声明指针,不选择直接声明这个对象?
在C++中选择使用指针而不是直接声明对象通常是为了获得更灵活的内存管理和功能。具体到Qt中的QMenu *manageMenu;
,选择声明指针而不是直接声明对象的原因可能包括以下几点:
- 动态内存分配
使用指针可以动态地在程序运行时创建对象,而不是在编译时确定。通过指针,开发者可以在需要时通过new
关键字创建对象,灵活控制对象的生命周期。这对需要延迟初始化的对象特别有用。例如,一个QMenu
对象可能只有在某个特定的用户操作后才需要创建,指针可以实现这一点。
cpp
manageMenu = new QMenu(this);
如果直接声明对象(不使用指针),对象会在声明时立即被构造,占用内存资源。例如:
cpp
QMenu manageMenu;
这样对象会立即创建,但可能会浪费内存资源,因为有时对象并不总是立刻需要。
- 多态性和继承
在面向对象编程中,指针允许多态性操作。如果QMenu
有多个派生类,通过基类指针可以实现动态绑定。在Qt应用中,菜单可能会根据不同条件创建不同类型的菜单,这时使用基类指针来指向不同的派生类对象是常见的做法。
cpp
QMenu *menu = new CustomMenu(this);
这样通过指针指向派生类对象,可以方便地处理不同的菜单类型。
- 控制对象的生命周期
当通过指针创建对象时,你可以精确控制对象何时被创建、使用和销毁。通过直接声明对象(比如QMenu manageMenu;
),它会在函数退出或对象超出作用域时自动销毁。但有时你希望对象在其作用域之外也能存在,指针可以用来延长对象的生命周期。
- 使用指针时,开发者可以选择在何时销毁对象(通常使用
delete
释放内存),从而避免作用域结束时对象被自动销毁。
-
Qt的父子对象管理机制
在Qt中,许多对象(如
QMenu
、QWidget
等)支持父子关系。当一个对象有父对象时,父对象会负责管理和销毁其子对象。如果使用指针并在创建对象时将父对象传递给它(如new QMenu(this);
),那么这个菜单的内存会被自动管理,并在父对象销毁时被自动销毁。这样避免了手动调用delete
来释放内存。 -
避免栈内存的限制
在某些情况下,特别是在大型应用程序中,直接在栈上声明大对象可能会导致栈溢出。使用指针可以将对象分配在堆上,从而避免这个问题,尤其是对于那些占用内存较大的对象。
-
跨作用域使用对象
指针允许你在函数之外或多个函数之间共享同一个对象。这样你可以将对象在多个函数之间传递而不需要复制对象。
小结:
- 指针:更灵活的内存管理(动态分配)、延迟初始化、多态支持、父子对象自动管理、跨作用域使用。
- 直接声明对象:简单直观,适用于不需要动态内存管理的情况,但不适合需要灵活控制生命周期或延迟初始化的场景。
选择使用指针主要是为了更灵活地管理对象的生命周期和内存资源,特别是在需要动态创建对象或者依赖父子对象机制的场景中。
既然有动作,那肯定会涉及到信号与槽函数
如何去关联这些元素?
connect(ui对象,动作.clicked,槽函数(子窗口的创建))
connect函数是在调用的时候用,并不是用在声明里面吧?声明里面把信号声明出来就行了
如何声明信号?
slot
- 这些信号就是对应的功能函数了,
这些功能函数具体应该实现什么呢?
这个函数 Widget::on_manageMenu_clicked() 是一个槽函数(Slot),用于响应用户点击某个界面元素(比如一个按钮或者菜单项)的事件。在 Qt 中,槽函数是与信号机制一起使用的,当特定事件发生时(如按钮被点击),信号会触发对应的槽函数。
具体解释:
Widget::on_manageMenu_clicked(): 这是类 Widget 的成员函数,函数名表明它是一个槽函数,用于处理用户点击了名为 manageMenu 的某个可点击元素(可能是按钮、菜单项等)的事件。
ui: 这是通常由 Qt 的 UI 设计器生成的指针,指向用户界面(UI)的控件集合。通过 ui 对象,你可以访问并操作在 UI 设计器中定义的各个控件。
stackedWidget: 这是一个 QStackedWidget 控件的实例。QStackedWidget 是一个在同一位置显示多个小部件的容器控件,但一次只能显示一个。它的作用是将多个子控件(窗口、页面等)堆叠在一起,并通过索引来选择当前显示的控件。
setCurrentIndex(0): 这个方法用于设置 QStackedWidget 显示的页面。setCurrentIndex(0) 表示将当前显示的页面设置为索引为 0 的页面。QStackedWidget 按照顺序组织子控件,从 0 开始编号。所以这行代码的意思是显示堆栈中的第一个页面。
函数作用:
当用户点击了与 manageMenu 相关联的界面元素时,槽函数 on_manageMenu_clicked() 将被触发。函数的作用是让 QStackedWidget 切换到第一个页面(索引 0)。
使用场景:
假设你的界面是一个多页面的应用,比如一个设置界面,有多个子页面(如"主页"、"设置"、"关于"等)。stackedWidget 就是管理这些子页面的控件,而这个槽函数的作用就是在点击"管理菜单"(manageMenu)时,显示第一页的内容。例如:
setCurrentIndex(0) 可能会显示"主页"或"管理界面"等第一个页面的内容。
通过这种机制,你可以轻松地在不同的页面之间切换。
别忘了,最后还需要一个生成菜单栏的函数,因为这些都是在菜单栏里面的。
QWidget这个基类用来做什么的?
QWidget
是 Qt 框架中所有用户界面对象的基类,代表一个窗口组件或可视化元素。几乎所有图形用户界面(GUI)元素都是从 QWidget
派生的,它为这些元素提供了基本的绘制和事件处理功能。在 Qt 中,QWidget
既可以作为一个独立的窗口使用,也可以作为一个容器来承载其他子组件。
QWidget
的主要功能和用途:
-
窗口和容器的基础类
-
QWidget
是所有可视化元素的基类,例如按钮(QPushButton
)、标签(QLabel
)、文本框(QLineEdit
)等。 -
QWidget
也可以作为窗口(顶层窗口或子窗口)来使用。如果设置了QWidget
的某个对象为顶层窗口,它将拥有窗口装饰(标题栏、关闭按钮等)。例如:cppQWidget window; window.setWindowTitle("Example Window"); window.show();
-
作为容器,它可以包含其他
QWidget
对象。通过设置父子关系,父QWidget
会自动管理和排列其子控件。
-
-
绘图区域
-
QWidget
提供了一个矩形的绘制区域,并支持通过事件处理机制自定义绘制。通过重写QWidget::paintEvent(QPaintEvent *event)
,可以绘制图形或自定义组件的外观。cppvoid MyWidget::paintEvent(QPaintEvent *event) { QPainter painter(this); painter.drawLine(0, 0, 100, 100); }
-
使用
QPainter
类可以绘制文本、形状、图像等。
-
-
事件处理
QWidget
提供了丰富的事件处理机制,支持各种用户交互的事件,如鼠标事件、键盘事件、窗口大小变化事件等。你可以通过重写这些事件处理函数来自定义控件的行为:mousePressEvent(QMouseEvent *event)
: 处理鼠标按下事件。keyPressEvent(QKeyEvent *event)
: 处理键盘按键事件。resizeEvent(QResizeEvent *event)
: 处理窗口大小改变事件。
-
布局管理
-
QWidget
提供了布局管理功能,能够合理地管理子组件的位置和大小。通过使用布局管理器(例如QVBoxLayout
,QHBoxLayout
,或QGridLayout
),可以将多个QWidget
放置在父容器内,并根据窗口大小自动调整它们的布局和排列。cppQWidget *window = new QWidget; QVBoxLayout *layout = new QVBoxLayout; layout->addWidget(new QPushButton("Button 1")); layout->addWidget(new QPushButton("Button 2")); window->setLayout(layout); window->show();
-
-
信号和槽机制
-
QWidget
继承了QObject
类,因此支持 Qt 的信号和槽机制。这是 Qt 的核心特性之一,用来在不同对象之间传递信息,尤其适用于用户交互操作。例如,点击按钮时可以发出一个信号,并连接到一个槽函数来处理点击事件。cppQPushButton *button = new QPushButton("Click Me", this); connect(button, &QPushButton::clicked, this, &MyWidget::onButtonClick);
-
-
窗口和对话框
QWidget
可以作为顶层窗口使用,通过show()
方法将其显示为一个独立的窗口。如果设置QWidget
的父对象为空,则它将成为顶层窗口。- 可以派生出更复杂的窗口类型,例如
QMainWindow
,这类窗口提供更多的标准化功能,如菜单栏、工具栏和状态栏。
-
输入控件和交互
QWidget
作为基类提供了基本的用户交互功能,比如处理键盘输入、鼠标点击、拖放操作等。派生类可以在此基础上扩展功能,生成各种输入控件。
典型的 QWidget
派生类
以下是一些从 QWidget
派生的常见类:
QPushButton
: 按钮。QLabel
: 显示文本或图像的标签。QLineEdit
: 单行文本输入框。QTextEdit
: 多行文本编辑框。QMainWindow
: 主窗口类,带有菜单栏、工具栏和状态栏。
总结
QWidget
是 Qt 用户界面库中最基本的可视化元素,提供了窗口、容器、绘图、事件处理等功能,几乎所有的 GUI 组件都是从它派生的。
class Widget : public QMainWindow这边为什么把基类给改了
方便创建菜单栏
在 Qt 中,将一个类从 QMainWindow
继承(如 class Widget : public QMainWindow
)而不是从 QWidget
继承,通常是为了获得 QMainWindow
特有的功能和结构。QMainWindow
是专门设计用于创建主窗口(Main Window)类型的类,它提供了许多标准的用户界面元素和布局管理功能,而这些功能在简单的 QWidget
中是没有的。
区别和原因:
-
QMainWindow
提供更多的主窗口功能
QMainWindow
是一个复杂的窗口类,专门用于设计应用程序的主窗口。它比QWidget
提供了更多的布局区域和功能。具体来说,QMainWindow
有以下几个特定区域:-
菜单栏(Menu Bar):允许添加一个全局的菜单栏,通常用于包含"文件"、"编辑"等菜单选项。
cppQMenuBar *menuBar = new QMenuBar(this); setMenuBar(menuBar);
-
工具栏(Tool Bar):可以方便地添加一个工具栏,包含快捷工具按钮。
cppQToolBar *toolBar = new QToolBar("Main Toolbar", this); addToolBar(toolBar);
-
状态栏(Status Bar):位于窗口的底部,显示一些状态信息。
cppQStatusBar *statusBar = new QStatusBar(this); setStatusBar(statusBar);
-
中央区域(Central Widget) :主窗口的中央区域可以放置主内容部件(通常是一个复杂的 UI 组件,比如文本编辑器、绘图区域等)。你可以使用
setCentralWidget()
方法指定这个区域的主内容。cppQWidget *centralWidget = new QWidget(this); setCentralWidget(centralWidget);
相比之下,
QWidget
只是一个基本的窗口部件,没有这些特定的区域管理功能。如果你的应用程序需要这些功能,那么从QMainWindow
继承会让设计和实现更简单和规范。 -
-
布局管理
QMainWindow
提供了一种专门的布局方式,允许你直接使用菜单栏、工具栏、状态栏等区域,并且还提供了setCentralWidget()
方法,用于将主窗口的中央内容部件嵌入到主窗口的布局中。使用
QWidget
作为基类时,你需要手动管理布局,例如使用QVBoxLayout
或QHBoxLayout
来放置菜单、工具栏和其他内容。而QMainWindow
提供了更方便的接口,使你可以专注于内容部分,而不需要手动管理整体布局。 -
更加标准化的主窗口设计
如果你的应用程序需要一个标准的桌面应用程序主窗口布局,例如带有菜单栏、工具栏和状态栏的窗口,使用
QMainWindow
会更符合用户对传统桌面应用程序的预期。在这种情况下,从QMainWindow
继承能够让代码更加简洁、直观,也避免了在QWidget
中手动创建和管理这些元素的复杂性。 -
应用场景决定选择
选择
QMainWindow
还是QWidget
取决于你构建的窗口类型:- 如果你构建的是一个简单的窗口,例如一个对话框或一个简单的控件容器,
QWidget
是合适的选择。 - 如果你构建的是一个功能丰富的主窗口,需要有菜单栏、工具栏、状态栏等典型的桌面应用程序布局,
QMainWindow
会是更好的选择。
- 如果你构建的是一个简单的窗口,例如一个对话框或一个简单的控件容器,
总结
把基类改为 QMainWindow
是为了利用其特有的功能,如菜单栏、工具栏、状态栏和中央窗口布局等。QMainWindow
提供了一个完整的主窗口框架,适合创建功能复杂、符合桌面应用程序标准的窗口。如果你需要这些主窗口特性,继承 QMainWindow
是更合适的选择。
Stacked Widget控件
QStackedWidget
是 Qt 中的一种控件,它可以管理多个子窗口(widgets),但一次只显示其中的一个。这使得 QStackedWidget
非常适合用于场景切换、页面导航等应用场景,比如选项卡式界面、向导式界面等。
QStackedWidget
的主要特点:
-
多页面管理:
QStackedWidget
可以堆叠多个子控件,但在同一时刻只显示其中的一个。通过修改索引,可以轻松地在这些页面之间进行切换。
-
显示控制:
QStackedWidget
提供了类似"上一页"和"下一页"的功能,可以通过索引切换页面。你也可以通过槽函数(如按钮点击)直接切换到特定的页面。
-
典型应用场景:
- 向导式界面 :可以使用
QStackedWidget
来实现步骤式界面,每个步骤作为一个页面,通过"下一步"按钮切换。 - 选项卡式界面 :如果想隐藏选项卡的切换控件,也可以用
QStackedWidget
来手动管理页面的显示。
- 向导式界面 :可以使用
基本操作方法:
- 添加页面
你可以向QStackedWidget
中添加任意多个页面(子控件),每个页面都是一个QWidget
或其派生类的实例。例如:
cpp
QStackedWidget *stackedWidget = new QStackedWidget(this);
QWidget *page1 = new QWidget();
QWidget *page2 = new QWidget();
stackedWidget->addWidget(page1);
stackedWidget->addWidget(page2);
- 切换页面
QStackedWidget
通过索引来管理各个页面,从0
开始编号。你可以通过以下方法来切换显示的页面:
-
通过索引切换页面 :
cppstackedWidget->setCurrentIndex(0); // 显示第一个页面 stackedWidget->setCurrentIndex(1); // 显示第二个页面
-
通过指定的页面切换 :
cppstackedWidget->setCurrentWidget(page1); // 显示特定的页面
- 获取当前页面
你可以获取当前显示的页面或其索引值:
cpp
QWidget *currentPage = stackedWidget->currentWidget(); // 获取当前页面
int currentIndex = stackedWidget->currentIndex(); // 获取当前页面索引
- 插入和移除页面
你可以动态地插入或移除页面:
-
插入页面:
cppstackedWidget->insertWidget(1, newPage); // 在索引1处插入新页面
-
移除页面:
cppQWidget *removedPage = stackedWidget->widget(1); // 获取索引1处的页面 stackedWidget->removeWidget(removedPage); // 移除该页面
总结:
QStackedWidget
是一个堆叠多个子窗口的控件,一次只显示一个。通过索引或控件指针可以切换显示的页面,非常适合用于多页面的场景,如向导、切换视图等应用。
创建菜单栏函数
业务逻辑是怎样?
设置几个按钮的信号与槽机制