元对象
-
要在 Qt Creator 中启动元对象系统包括 Q_OBJECT 宏类的定义必须在头文件中,否则 moc 工具不能生成元对象代码
-
若定义了 QObject 并构建了类的衍生类,再添加 Q_OBJECT 宏,则此时(“构建”>“执行 qmake”),否则 moc 无法生成代码
-
满足以下三个条件:
- 这类必须继承自己 QObject 类。
- 必须在类声明添加 Q_OBJECT 宏,用于启动元对象特征,然后可以使用动态特征、信号和槽等功能。
- *元对象编译器(moc)为每个 QObject 实现元对象特征所必需的子类代码
- 多重继承时 QObject 必须位于基类列表中的第一位
- QMetaObject 类描述了 QObject 所有元信息及其衍生对象,QMetaObject 类的对象是 Qt 中元对象。
- 描述成员
- 函数成员使用类QMetaMethod 进行描述
- 属性使用 QMetaProperty 描述类别等,
- 使用QMetaObject 描述整个类对象
使用 Qt 反射机制的条件
- 需要继承自 QObject 类,需要添加到类中 宏。
- 注册成员函数:如果希望普通成员函数能被反射,则需要在函数声明前添加 宏。
- 注册成员变量:如果要求成员变量反射,则需要使用 宏
Q_PROPERTY(type name (READ getFunction [WRITE setFunction] | MEMBER memberName [(READ getFunction | WRITE setFunction)]) [RESET resetFunction] [NOTIFY notifySignal] [REVISION int] [DESIGNABLE bool] [SCRIPTABLE bool] [STORED bool] [USER bool] [CONSTANT] [FINAL])
- type:指定属性的类型可以是 QVariant 如果是枚举类型,则需要使用支持类型或用户自定义类型 Q_ENUMS 红对枚举注册,如果是自定义类型,则需要使用Q_DECLARE_METATYPE( Type )宏注册(详见后文)。
- name:指定属性的名称。
- READ getFunction: 用于指定读取函数(读取属性值) READ 表示读取,不能改变,getFunction用于指定函数名称。 若没有指定 MEMBER 必须指定变量 READ 函数。READ 函数是 const 的,READ 函数必须返回属性类型或引导该类型 用。
- WRITE setFunction: ? 用于指定设置函数(设置属性值) WRITE 表示写入,不能改变,setFunction 用于指定函数名称。该函数必须只有一个参数,返回值类型必须是 void。 ? 如果只读属性,则无需指定 WRITE 函数。
- MEMBER memberName 用于变量指定的成员 memberName 。其中 MEMBER 表示成员,不能改变,memberName 表示类中的成员变量。如果没有指定 READ 函数,则 MEMBER 变量。
- RESET resetFunction:用于将属性重置为默认值,函数无参数,返回值必须为 void。其中 RESET 表示重置,不能更改resetFunction 用于指定函数名称。
- NOTIFY notifySignal:表示给属性。该项目设置时,应指定该类别 存在的信号每当属性值发生变化时都会发出。如果使用, MEMBER 变量, 则 NOTIFY 信号,参数必须与属性类型相同,并接受属性的新值。
- REVISION:默认设置版本号 0。
- DESIGNABLE:用于设置属性 ,大多数属性是可见的,默认值是 ture,可见。该变量还可以指定返回布尔值的成员函数来替代它 true 或 false。
- SCRIPTABLE:默认设置属性是否可以被脚本引擎访问 true
- STORED:在保存对象的状态下是否必须保存属性值。大多数属性的这个值是 true
- USER:设置属性是否为可编辑属性,每个类只有一个 USER 属性(默认值为 false)。比如 QAbstractButton::checked 是用户可编辑的属性
- CONSTANT:表示属性值为常量,不能有常量属性WRITE函数和NOTIFY信号。对于同一对象的例子,每次使用常量属性 READ 函数必须得到相同的值,但对于不同类别的例子,这个值可以不同。
- FINAL:表示属性不能被派生类重写。
Q_DECLARE_METATYPE( Type ) 注册一种类型QVariantk可以识别
信号和槽
定义信号规则
- 信号使用 关键词声明后面有冒号: public、private、protected 信号默认为访问控制符 public 的。
- 信号只能像函数一样声明,其中可以有参数。参数的主要功能是与槽通信,就像普通函数的参数传输规则一样。虽然信号就像一个函数,但它的呼叫方式不同,需要使用信号 关键字发射。
- 信号,,信号是由 moc 自动生成。
- 信号返回值是 void 类型的。
槽应符合下列规定
- 需要使用声明槽 slots 关键字,在其后面有一个冒号“:”,且槽需使用 public、private、protected 访问控制符之一。
- 槽是一种普通函数,可以像使用普通函数一样使用和普通函数的主要功能是的,槽可以与信号相关
信号与槽的关系
- 槽的类型需要与信号参数的类型相对应,
- 槽的参数不能是多余的信号参数,因为如果槽的参数更多,多余的参数不能接收信号传输的值。如果这些多余的无值参数用于槽中,就会出错。
- 如果信号的参数是多余槽的参数,则多余的参数将被使用。
- 一个信号可以与多个槽相关,多个信号也可以与同一个槽相关,信号也可以与另一个信号相关。
- 若一个信号与多个槽相关,则发射信号时,槽函数按相关顺序执行。
- 如果信号连接到另一个信号,当第一个信号发射时,第二个信号将立即发射
信号与槽的关联(连接) Connect
- 形式1:
static QMetaObject::Connection connect( const QObject *sender, ////发射信号的对象指针 const char *signal, //发送的信号 必须使用 SIGNAL()宏 const QObject *receiver, ////接收信号的对象指针 const char *method, // 接收信号的槽函数,SLOT()宏,若需要使用信号 SIGNAL 宏 Qt::ConnectionType type = Qt::AutoConnection)
实例
class A:public QObject {Q_OBJECT singals: void s(int i);};
class B:public QObject{Q_OBJECT public slots: void x(int i){}};
A ma; B mb;
QObject::connect (&ma, SIGNAL( s(int) ), &mb, SLOT(x(int) );
Qt::ConnectionType 的取值(type 参数的取值)枚举值 | 说明 |
---|---|
Qt::AutoConnection 0 | (自动关联,默认值)。若接收者驻留在发射信号的线程中(即,。当信号发射时确定使用哪种关联类型。 |
Qt::DirectConnection 1 | 直接关联。当信号发射后,立即调用槽。在槽行完之后,才会执行发射信号之后的代码(即 emit 关键字之后的代码)。该槽在信号线程中执行。 |
Qt::QueuedConnection 2 | 队列关联。当控制权返回到接收者线程的事件循环后,槽才会被调用,也就是说 emit 关键字后面的代码将立即执行,槽将在稍后执行,该槽在接收者的线程中执行。 |
Qt::BlockingQueuedConnection 3 | 阻塞队列关联。和 Qt :: QueuedConnection 一样,只是信号线程会一直阻塞,直到槽返回。如果接收者驻留在信号线程中,则不能使用此连接,否则应用程序将会死锁。 |
Qt::UniqueConnection 0x80 | 唯一关联。这是一个标志,可使用按位或与上述任何连接类型组合。当设置 Qt :: UniqueConnection 时,则只有在不重复的情况下才会进行连接,如果已经存在重复连接(即,相同的信号指向同一对象上的完全相同的槽),则连接将失败,此时将返回无效的 QMetaObject::Connection |
- 形式2:
QMetaObject::Connection connect(
const QObject *sender,
const char *signal,
const char *method,
Qt::ConnectionType type = Qt::AutoConnection) const
A ma;
B mb;
mb.connect(&ma, SIGNAL(s(int)), SLOT(x(int));
- 形式3
static QMetaObject::Connection connect(
const QObject *sender,
PointerToMemberFunction signal,
const QObject *receiver,
PointerToMemberFunction method,
Qt::ConnectionType type = Qt::AutoConnection)
例子
A ma;
B mb;
QObject::connect(&ma, &A::s, &mb, &B::x );
- 形式4
static QMetaObject::Connection connect(
const QObject *sender,
PointerToMemberFunction signal,
Functor functor)
示例:假设 void s(int i)是类 A 中定义的信号,void x(int i)是类 B 中定义的, 则
A ma;
QObject::connect(&ma, &A::s, &B::x );
signals、slots、emit 关键字原型
- 在以上关键字上右击然后按下 F2,在 qobjectdefs.h 文件中可以看到这些关键字的原型
- signals 关键字:最终被#define 置换为一个访问控制符,其简化后的语法为#define signals public
- slots 关键字:最终被#define 置换为一个空宏,即简化后的语法为:#define slots
- emit 关键字:同样被#define 置换为一个空宏,即简化后为:#define emit
- 由以上各关键字原型可见,
事件
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-6OPOzmIU-1632751916577)(./pic/application.png)]
- QCoreApplication:主要提供无 GUI 程序的事件循环。
- QGuiApplication:用于管理 GUI 程序的控制流和主要设置。
- QApplication 专门为 QGuiApplication 提供基于 QWidget 的程序所需的一些功能
- 初始化应用程序
- 执行事件处理
- 解析常用命令行参数
- 定义了应用程序的界面外观,可使用 QApplication::setStyle()进行更改
- 使用 QCoreApplication::translate()函数对字符串进行转换。
- 通过 QApplication::desktop()函数处理桌面,通过 QCoreApplication::clipboard()函数处理剪贴板。
- 管理应用程序的鼠标光标
Qt 事件event
- 继承关系 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-KH1wsSvL-1632751916580)(./pic/event.png)]
事件和信号的区别
- 他们两个是不同的概念,不要弄混淆。信号是由对象产生的,而事件则不一定是由对象产生的(比如由鼠标产生的事件),事件通常来自底层的窗口系统,但也可以手动发送自定义的事件,可见信号和事件的来源是不同的。
- 事件既可以同步使用,也可以异步使用 (取决于调用 sendEvent()还是 postEvents()),而使用信号和槽总是同步的。事件的另一个好处是可以被过滤。
- QEvent::accept()函数表示接受一个事件,使用 QEvent::ignore()函数表示忽略一个事件。
- QCloseEvent(关闭事件)有一些不同,QCloseEvent::ignore()表示取消关闭操作,而QCloseEvent::accept()则表示让 Qt 继续关闭操作。
Qt 实现事件过滤器的步骤如下:
- Qt 调用
void QObject::installEventFilter (QObject* filterObj)
把 filterObj 对象设置安装(或注册)为事件过滤器,filterObj 也称为过滤器对象。事件过滤器通常在构造函数中进行注册。 2. 在上一步注册的 filterObj 对象,通过调用
bool QObject::eventFilter(QObject* obj, QEvent* e);
来接收拦截到的事件。也就是说拦截到的事件在 filterObj 对象中的 eventFilter 函数中处理。eventFilter 的第一个参数 obj 指向的是事件本应传递到的 3. 使用
QObject::removeEventFilter(QObject *obj)
函数可以删除事件过滤器。
eventFilter()函数可以接受或拒绝拦截到的事件, - 若该函数返回 false,则表示事件需要作,此时事件会被发送到目标对象本身进行处理(注意:这里并未向父对象进行传递), - 若 evetnFilter()返回 true,则表示,此时目标对象和后面安装的事件过滤器就无法获得该事件
自定义事件发送
// 直接发送给接收事件的目标对象
static void QCoreApplication::postEvent (
QObject* receiver, //指向接收事件的对象
QEvent* event, //需要发送的事件
int priority=Qt::NormalEventPriority);//事件的优先级
static bool QCoreApplication::sendEvent(
QObject* receiver,
QEvent* event)
- QWidget :: setMouseTracking()函数启用鼠标跟踪后,就即使不按下鼠标按钮也会产生鼠标移动事件
枚举值 | 值 | 说明 |
---|---|---|
Qt::NoButton | 0x0000 0000 | 按钮状态不指向任何按钮。 |
Qt::LeftButton | 0x0000 0001 | 按下左键 |
Qt::RightButton | 0x0000 0002 | 按下右键 |
Qt::MidButton 或 Qt::MiddleButton | 0x0000 0004 按下中键 |
鼠标和键盘事件共同使用的类及函数
- 通过调用从 QInputEvent::modifiers()函数可以查询键盘修饰键的状态。
- 使用 QWidget::etEnable()函数可以启用或禁用部件的鼠标和键盘事件。
- 键盘修饰键(即 Ctrl、Alt、Shift 等键)使用枚举类型 Qt::KeyboardModifier 来描述,其取值如下表
枚举值 | 值 | 说明 |
---|---|---|
Qt::NoModifier | 0x0000 0000 | 无修饰键被按下 |
Qt::ShiftModifier | 0x0200 0000 | 按下 Shift 键 |
Qt::ControlModifier | 0x0400 0000 | 按下 Ctrl 键 |
Qt::AltModifier | 0x0800 0000 | 按下 Alt 键 |
Qt::MetaModifier | 0x1000 0000 | 按下 Meta 键(windows 系统为 windows 键) |
Qt::KeypadModifier | 0x2000 0000 | 按下小键盘上的键 |
Qt::GroupSwitchModifier | 0x4000 0000 | 按下 Mode_switch 键(仅限 X11) |
鼠标事件 QMouseEvent
QMouseEvent(
Type type, //鼠标事件的类型
const QPointF &localPos, //鼠标光标的位置
Qt::MouseButton button,//产生鼠标事件的按钮,若事件类型是 MouseEvent,则此值是Qt::NoButton
Qt::MouseButtons buttons, //哪些鼠标按钮处于按下状态
Qt::KeyboardModifiers modifiers);//键盘修饰键
键盘事件 QKeyEvent
- 按键与自动重复:自动重复是指按下键盘上的键(修饰键除外)不放时,会不断重复的发送键按下事件,Qt 默认是启用自动重复的,若要实现类似按键 A+D 之类的快捷键,就需要关闭自动重复。可使用如下方法来关闭自动重复if( QKeyEvent::isAutoRepeat() ) return; // 若自动重复则什么也不做
- 压缩按键事件
QKeyEvent (
Type type, //type:表示键盘事件的类型,必须是 QEvent::KeyPress、QEvent::KeyRelease QEvent::ShortcutOverride 之一
int key, //描述键代码的 Qt::Key 枚举值
Qt::KeyboardModifiers modifiers, //键盘的修饰键
const QString &text = QString(), //按键生成的 Unicode 字符
bool autorep = false, //是否启用自动重复
ushort count = 1)//产生该事件时的按键数量
小结
QEvent 类
-
QEvent(Type type) //构造函数,用于创建自定义事件
-
virtual ~QEvent() //析构函数
-
void accept() //接受事件
-
void ignore() //忽略事件
-
void setAccepted(bool a) //设置是否接受事件
-
Type type() const //返回事件的类型
-
static int registerEventType(int hint=-1): 注册并返回自定义事件类型,使用该函数的返回值可保证自定义的事件不会有重复的 Type 枚举值。
-
enum Type{None, ActionAdded, … Keypress,…} //定义事件的类型,详见帮助文档
QObject 类
- virtual bool event() //接收并处理事件,先于默认的事件处理函数
- void installEventFilter(QObject *finterObj); //安装(或注册)事件过滤器
- vitrual bool eventFilter(QObject* w , QEvent *e ) //用于接收并处理事件过滤器对象接收的事件。
- void removeEventFilter(QObject* obj); //移除事件过滤器。
QCoreApplication 类
- virtual bool notify(QObject* r, QEvent* e) //该函数用于分发事件
- int exec(); //使用该函数进入事件主循环。
- void postEvent(QObject* r, QEvent* e, int priority=Qt::NormalEventPriority); //用于发布自定义事件
- bool sendEvent(QObject* r, QEvent *e); //用于发送自定义事件
QWidget 类
- void grabKeyboard() //捕获键盘输入
- void grabMouse() //捕获鼠标输入
- void grabMouse(const QCursor& c); //捕获鼠标输入
- QWidget* keyboardGrabber(); //返回捕获键盘输入的部件
- QWidget* mouseGrabber(); //返回捕获鼠标输入的部件
- void releaseMouse() //释放捕获的鼠标输入
- void releaseKeyboard() //释放捕获的键盘输入。
- bool hasMouseTracking() const; //是否启用鼠标跟踪
- void setMouseTracking(bool enable) //设置鼠标跟踪状态
- bool underMouse() const; //部件是否位于鼠标光标之下
- void setAttribute ( Qt::WidgetAttribute attribute, bool on=true); //设置是否启用键压缩。
- bool testAttribute(Qt::WidgetAttribute attribute) const //返回是否启用了键压缩。
QWidght
事件
moveEvent()
resizeEvent()
当,若部件可见,则会产生 moveEvent()事件,若部件时可见,则会产生 resizeEvent()事件,当更改部件的几何形状,若部件可见时,会产生 moveEvent()或 resizeEvent()事件,
Qt 对窗口位置和大小进行描述的属性
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-NDktVdMK-1632751916581)(./pic/sizexy.png)]
控件默认大小
virtual QSize sizeHint() const;
- 可以重新实现该函数以指定部件的默认大小
窗口状态
Qt::WindowStates windowState() const;
void setWindowState(Qt::WindowStates windowState);
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YFpRfZfL-1632751916582)(./pic/WindowState.png)]
标题、透明度、启用/禁用
//标题
QString windowTitle() const;
void setWindowTitle(const QString &);
//保存与部件相关联的路径
QString windowFilePath() const;
void setWindowFilePath(const QString& filePath);
透明度
//标题
qreal windowOpacity() const;
void setWindowOpacity(qreal level);
// 1.0(不透明)到 0.0(透明),
光标有关的属性
QCursor cursor() const;
void setCursor(const QCursor&);
void unsetCursor();
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-uTnBxqTq-1632751916583)(./pic/CursorShape.png)]
布局管理
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-fTduoQqS-1632751916584)(./pic/layout.png)]
- 布局项目(重要概念):是指由布局管理的元素,包括 QWidget 部件、QLayout 布局,还有间距 QSpacerItem、QLayoutItem 等,其中 QLayoutItem 是用于描述由布局管理的项目的抽象类
- 由 QHBoxLayout 类实现的水平布局,效果如下图
- 由 QVBoxLayout 类实现的垂直布局,效果如下图
- 由 QGridLayout 类实现的二维网格布局,效果如下图
- 由 QFormLayou 实现的两列表格布局,效果如下图 [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Fip3dBs1-1632751916585)(./pic/layout_class.png)]
Qt 使用布局管理器的步骤为,
- 首先创建一个布局管理器类的对象
- 然后使用该布局管理器类中的 addWidget()函数,把需要由布局管理器管理的部件添加进来。还可使用 addLayout()函数把其他布局管理器添加进来。
- 最后使用 QWidget::setLayout()函数为窗口设置布局管理器。
说明:
**
- 若为布局指定了父部件,则可以不使用 QWidget::setLayout()函数反之,调用QWidget::setLayout()函数安装布局,则可以不为该布局指定父部件。
- 不需要为添加到布局中的部件指定父部件,布局中的部件会自动成为安装布局的部件的子部件(使用 QWidget::setParent())。注意:子部件的父部件不是布局,而是安装布局的部件**
设置拉伸因子的函数
//为索引为 index(从 0 开始)的部件设置拉伸因子
bool QBoxLayout::setStretch(int index, int stretch);
//为部件 widget 设置拉伸因子。
bool QBoxLayout::setStretchFactor(QWidget* widget, int stretch);
//返回索引 index 处的拉伸因子。
int QBoxLayout::stretch(int index) const;
QWidget 类中对部件大小进行限制的属性
大小属性 | 说明 |
---|---|
1. sizeHint | 默认大小 |
2. minimumSizeHint | 部件的最小大小提示 |
3. minimumSize | 部件的最小大小 |
4. maximumSize | 部件的最大大小 |
QSizePolicy 类
QSizePolicy sizePolicy() const;
void setSizePolicy(QSizePolicy);
void setSizePolicy(
QSizePolicy::Policy horizontal,
QSizePolicy::Policy vert);
//表示设置水平方向的大小策略
QSizePolicy::setHorizontalPolicy(Policy)
//表示设置水平方向的拉伸因子
QSize::setHorizontalStretch(int)
- 该类用于描述布局的大小调整策略
QSizePolicy::Policy 枚举 | 说明 |
---|---|
QSizePolicy::Fixed | 部件,其大小始终为 sizeHint 的大小。 |
QSizePolicy::Minimum | 部件的是其大小,部件可以拉伸,但不能压缩得比大小提示更小。部件拉伸范围为 sizeHint~无限 |
QSizePolicy::Maximum | 部件的大小提示是其最大大小,部件可以压缩,但不能拉伸得比大小提示更大。部件拉伸范围为 minimumSizeHint~sizeHint |
QSizePolicy::Preferred | 部件可,但大小提示仍是合适的大小。部件拉伸范围是minimumSizeHint~无限 |
QSizePolicy::Expanding | 部件可,但更希望是拉伸,设置该策略的部件。部件拉伸范围是 minimumSizeHint~无限。 |
QSizePolicy::MinmumExpanding |
部件的大小提示是其最小大小,部件可以拉伸,但不能压缩得比大小提示更小,设置该策略的部件拥有。部件拉伸范围为 sizeHint~无限。注:这种策略可能会被淘汰。 |QSizePolicy::Ignored |忽略大小提示,部件可任意拉伸和压缩。部件拉伸范围为minimumSizeHint~无限,注意:若 minimumSizeHint 的值为 0,则该策略可把部件压缩为 0 的大小(即部件不可见) ,除该策略外,其余策略是不能把部件压缩为 0 的大小的。
- 。
大小约束
- 大小约束其实就是用来设置主窗口的最大和最小值的
sizeConstraint sizeConstraint() const;
void setSizeConstraint(SizeConstraint);
QLayout::SizeConstraint 枚举 | 值 | 说明 |
---|---|---|
QLayout::SetDefaultConstraint | 0 | 把主窗口的最小大小设置为 QLayout::minimumSize(),除非主窗口已经具有最小大小,也就是说若主窗口已显示设置了最小大小,则此约束不会再使用 QLayout::minimumSize()设置主窗口的最小大小。这是默认值 |
QLayout::SetFixedSize | 3 | 主窗口的大小设置为 sizeHint();此时主窗口大小无法被调整,通常使用此约束使主窗口自动适应所布置的部件的大小。 |
QLayout::SetMinimumSize | 2 | 把主窗口的最小大小设置为 QLayout::minimumSize(),主窗口不能调整为比该大小更小。 |
QLayout::SetMaximumSize | 4 | 把主窗口的最大大小设置为 QLayout::maximumSize(),主窗口不能调整为比该大小更大。 |
QLayout::SetMinAndMaxSize | 5 | 把主窗口的大小设置为QLayout::minimumSize()~QLayout::maximumSize() |
QLayout::SetNoConstraint | 1 | 不对主窗口的大小进行设置(即没有约束),也就是说,保持主窗口之前的最大和最小大小,不对其进行更改。 |
A. 内容边距
布局中子部件和子部件之间的间距
QMargins QLayout::contentsMargins() const;
void QLayout::getContentsMargins(
int *left,
int *top,
int *right,
int *bottom) const;
void QLayout::setContentsMargins(
int left,
int top,
int right,
int bottom);
void QLayout::setContentsMargins(
const QMargins& margin);
B. 间距 spacing:指的是各部件之间的距离,
C. QSpacerItem 类 弹簧
- 使用该类可以创建自定义的间距,使用该类创建的间距相当于是一个,它是布局中的一个项目,会在布局中占据一个位置,布局会为其分,
//宽度为 w,高度为 h,水平方向的大小策略为hPolicy,垂直方向大小策略为 vPolicy 的间距
QSpacerItem(
int w,
int h,
QSizePolicy::Policy hPolicy = QSizePolicy::Minimum,
QSizePolicy::Policy vPolicy = QSizePolicy::Minimum) //构造函数
void changeSize(
int w,
int h,
QSizePolicy::Policy hPolicy = QSizePolicy::Minimum,
QSizePolicy::Policy vPolicy = QSizePolicy::Minimum)
//获取大小策略
QSizePolicy sizePolicy() const;
- 把大小为 size 的(QSpacerItem)添加到布局的末尾。
void QBoxLayout::addSpacing(int size);
- 在索引 index 处,插入大小为 size 的(QSpacerItem)。若索引为负,则在最后添加空格。
void QBoxLayout::insertSpacing(int index, int size);
- 把具有和拉伸因子为 strecth 的间距(QSpacerItem)添加到布局的末尾。
void QBoxLayout::addStretch(int strecth = 0);
- 在索引 index 处,插入,拉伸因子为 stretch 的可拉伸间距(QSpacerItem)。若索引为负,则在最后添加空格。
void QBoxLayout::insertStretch(int index, int stretch =0);
- 在索引 index 处,插入最小大小为 0,拉伸因子为 0 的 spacerItem。若索引为负,则在最后添加空格。
void QBoxLayout::insertSpacerItem(int index, QSpacerItem* spacerItem);
6. 把 spacerItem 添加到布局的末尾
```C++
void QBoxLayout::addSpacerItem(QSpacerItem* spacerItem);
嵌套布局
//在末尾添加布局。
void QBoxLayout::addLayout(
QLayout* layout,
int stretch = 0);
//在指定索引处插入布局,并设置其拉伸因子为 stretch,若 index 为负,则添加到末尾。
void QBoxLayout::insertLayout(
int index,
QLayout* layout,
int stretch = 0);
布局管理器类QBoxLayout、QBoxLayout、QFormLayout
QBoxLayout 子类 QHBoxLayout 和 QVBoxLayout
QBoxLayout::Direction 枚举(无标志) 作用:用于描述盒式布局的方向
QBoxLayout::Direction | 枚举 | 值 说明 |
---|---|---|
QBoxLayout::LeftToRight | 0 | 水平从左到右 |
QBoxLayout::RightToLeft | 1 | 水平从右到左 |
QBoxLayout::TopToBottom | 2 | 垂直从上到下 |
QBoxLayout::BottomToTop | 3 | 垂直从下到上 |
函数介绍
- QBoxLayout(Direction dir, QWidget* parent = Q_NULLPTR); //构造一个方向为 dir 的盒式布局
- 把布局layout添加到末尾或在指定索引index处插入布局,并设置其拉伸因子为stretch, 若 index 为负,则添加到末尾。
void addLayout(QLayout* layout, int stretch = 0);
void insertLayout(int index, QLayout* layout, int stretch = 0);
- 把部件 widget 添加到布局的末尾或添加到索引 index 处,并设置其拉伸因子为 stretch, 对齐方式为 m,默认对齐方式为 0,表示部件填充整个单元格。若 index 为负,则插入 到末尾。Qt::Alignment 属性见公共枚举章节。注意:对齐方式会对部件的拉伸效果产 生影响,非零对齐表示不应拉伸以填充其可用空间。
void addWidget(
QWidget* widget,
int stretch = 0,
Qt::Alignment m = Qt::Alignmnet());
void insertWidget(
int index,
QWidget* widget,
int stretch = 0,
Qt::Alignment m = Qt::Alignmnet());
- 在末尾添加或在索引 index 处插入大小为 size 的不可拉伸间距(QSpacerItem)。若索引 为负,则添加到末尾。
void addSpaceing(int size);
void insertSpacing(int index, int size);
- 在末尾添加或在索引 index 处,插入最小大小为 0,拉伸因子为 stretch 的可拉伸间距 (QSpacerItem)。若索引为负,则添加到末尾。
void addStretch(int stretch = 0);
void insertStretch(int index, int stretch = 0);
- 在末尾添加或在索引 index 处,插入最小大小为 0,拉伸因子为 0 的 spacerItem。若索 引为负,则添加到末尾。
void addSpacerItem(QSpacerItem* spacerItem);
void insertSpacerItem(int index, QSpacerItem* sp);
7. 设置 sapcing 属性
```C++
int spacing() const;
void setSpacing( int spacing);```
8. 分别表示,设置索引为 index 的部件或布局 layout 或部件 widget 的拉伸因子
为 stretch,若 layout 或 widget(不包括子布局)在布局中,则返回 true,否则返回 false。
```C++
void setStretch(int index, int stretch);
bool setStretchFactor(QWidget* widget , int stretch);
bool setStretchFactor(QLayout* layout, int stretch);
- //返回索引为 index 的拉伸因子
int stretch(int index) const;
- //返回布局的方向。
Direction direction() const;
- //设置布局的方向为 dir
void setDirection(Direction dir);
- 返回布局中的项目数。
virtual int count() const;
- 把盒式布局的正交尺寸限制在最小值 size 大小。其中正交尺寸是指,对于垂直布局则是指水平方向的尺寸,对于水平布局则是指垂直方向的尺寸。
void addStruct(int size);
- 把 item 插入到指定索引 index 处,若 index 为负,则插入到末尾。
void insertItem(int index, QLayoutItem* item);
- 从布局中 index 处的项目,并返回该项目,若没有这样的项目,则返回 0,删除项目后,布局中的其他项目会重新编号索引。
virtual QLayoutItem* takeAt(int index)
- QLayout::itemAt()的重新实现返回指定索引 index 处的项目,若没有这样的项目,则返回 0。
virtual QLayoutItem* itemAt(int index) const;
网格布局 QGridLayout
属性
- 以下属性用于获取或设置垂直和水平方向子部件之间的。
horizontalSpacing:int /*访问函数:*/int horizontalSpacing() const; void setHorizontalSpacing(int spacing);
verticalSpacing:int /*访问函数:*/int verticalSpacing()const; void setVerticalSpacing(int spacing);
函数
构造函数
QGridLayout();
QGridLayout(QWidget* parent); //构造函数
- 在 row 行,第 column 列单元格添加项目(layout、widget 或 item)
- 其对齐方式为 alignment。默认对齐方式为 0,表示部件会,非零对齐方式以填充可用空间
- 若 rowSpan 或columnSpan 为−1,则将 item 分别扩展至底部或右侧边缘。
void addLayout(
QLayout* layout,
int row,
int column,
Qt::Alignment alignment = Qt::Alignment());
void addLayout(
QLayout* layout,
int row, int column,
int rowSpan, int columnSpan,
Qt::Alignment alignment = Qt::Alignment());
void addWidget(
QWidget* widget,
int row,
int column,
Qt::Alignment alignment = Qt::Alignment());
void addWidget(
QWidget* widget,
int row,
int column,
int rowSpan,
int columnSpan,
Qt::Alignment alignment = Qt::Alignment());
void addItem(
QLayoutItem* item,
int row,
int column,
int rowSpan = 1,
int columnSpan = 1,
Qt::Alignment alignment = Qt::Alignment());
单元格的最小高度和宽度
1. int columnCount() const; //返回列数
2. int rowCount() const; //返回行数
3. int columnMinimumWidth(int column) const; //返回 column 列最小宽度
4. void setColumnMinimumWidth(int column, int minSize); //把column 列的**最小宽度**设置为minSize像素。
5. int rowMinimumHeight(int row) const; //返回 row 行的最小高度。
6. void setRowMinimumHeight(int row, int minSize); //把 row 行的**最小高度**设置为 minSize 像素。
设置的是 spcing 属性
1. int columnStretch(int column) const; //返回 column 列的拉伸因子
2. void setColumnStretch(int column, int stretch); //把 column 列的拉伸因子设置为 stretch。
3. int rowStretch(int row) const; //返回 row 行的拉伸因子。
4. void setRowStretch(int row, int stretch); //把 row 行的拉伸因子设置为 stretch。
5. void setSpacing(int spacing);// 把垂直和水平间距都设置为 spacing
6. int spacing() const; //若垂直和水平间距相等,则返回该值,否则返回−1。
表单布局 QFormLayout 类
- 、QFormLayout 被分成两列,左列是标签(label)部分,通常由标签 QLabel 组成,右列是由字段(field)部分
枚举
成员 | 值 | 说明 |
---|---|---|
QFormLayout::LabelRole | 0 | 标签部件 |
QFormLayout::FieldRole | 1 | 字段部件 |
QFormLayout::SpanningRole | 2 | 跨越标签和字段的部件(标签和字段间的间距?) |
- 设置或获取表单布局字段部分的(注意:
FieldGrowthPolicy fieldGrowthPolicy() const;
void setFieldGrowthPolicy(FieldGrowthPolicy);
成员 | 值 | 说明 |
---|---|---|
QFormLayout::FieldsStayAtSizeHint | 0 | 字段不超出他们的大小提示,QMacStyle 默认值 |
QFormLayout::ExpandingFieldsGrow | 1 | 的大小策略为 Expanding 或MinimumExpanding 的字段可以增长以填充可用的空间,其他字段不会超出他们的大小提示(原理见图示)。这是 QCommonStyle(比如 windows)的默认值 |
QFormLayout::AllNonFixedFieldsGrow | 2 | 的字会都会增长以填充可用空间,这是大多数样式的默认值(比如 Qt Extended 样式) |
Qt::Alignment formAlignment() const;
void setFormAlignment(Qt::Alignment);
Qt::Alignment labelAlignment() const;
void setLabelAlignment(Qt::Alignment)
- 表单行的方式
RowWrapPolicy rowWrapPolicy() const;
void setRowWrapPolicy(RowWrapPolicy)
QFormLayout::RowWrapPolicy枚举 | 值 | 说明 |
---|---|---|
QFormLayout::DontWrapRows | 0 | 字段始,这是除 Qt Extended 样式外的所有样式的默认策略。 |
QFormLayout::WrapLongRows | 1 | 标签获得足够宽的水平空间,以适应最宽的标签,其余空间分配给字段。若“标签,字段”对的最小大小比可用空间大,则字段被,这是 QtExtended 样式的默认策略。 |
QFormLayout::WrapAllRows | 2 | 字段始终 |
- 设置和获取部件之间的水平和垂直间距
//属性:horizontalSpacing:int 访问函数:
int horizontalSpacing() const; void setHorizontalSpacing(int);
//属性:verticalSpacing:int 访问函数:
int verticalSpacing() const; void setVerticalSpacing(int);
插入函数
//构造函数
1. QFormLayout(QWidget* parent = Q_NULLPTR);
//把 label 和 field 添加到末尾
2. void addRow(QWidget* label, QWidget* field);
void addRow(QWidget* labedl , QLayout* field);
//使用 labelText 作为文本创建一个 QLabel,并把其伙伴设置为 field
3. void addRow(const QString& labelText, QWidget* field);
//使用 labelText 作为文本创建一个 QLabel,并把该标签和 field 添加到末尾。
4. void addRow(const QString& labelText, QLayout* field);
//在末尾添加 widget,该部件占两列的宽度
5. void addRow(QWidget* widget);
//在末尾添加 layout,该部件占两列的宽度
void addRow(QLayout* layout);
6. void insertRow(int row, QWidget *label, QWidget* field);
void insertRow(int row, QWidget *label, QLayout* field);
void insertRow(int row, const QString &labelText, QWidget* field);
void insertRow(int row, const QString &labelText, QLayout* field);
void insertRow(int row, QWidget *widget);
void insertRow(int row, QLayout* layout);
QStackedLayout 类(分组布局或栈布局)
- 使用 QComboBox(组框)或 QListWidget(列表)之类的部件,提供给用户一个选择需要显示的页面的选项。
- 创建一个容器(比如 QWidget 实例),然后在该容器中添加需要显示给用户的内容。
- 把容器添加到 QStackedLayout 布局中。
- 把 QComboBox 的 activated 信号(或类似信号)与 QStackedLayout 的 setCurrentIndex 槽相关联,以实现当用户选择 QComboBox 中的选项时,显示 QStackedLayout 布局中的子部件。setCurrentIndex 槽的作用就是使 QStackedLayout 布局中的某一个子部件可见。
QStackedLayout 类的核心
- setCurrentIndex(int)和 setCurrentWidget(QWidget*)槽函数
- 要删除布局中的部件,可使用 QLayout::removeWidget()函数,
- 要获取布局中子部件的索引需使用 QLayout::indexOf()函数
QStackedLayout 类中的属性
- count:const int
//QLayout::count()的重新实现,返回布局中的项目数
virtual int count() const;
- currentIndex:int
//槽信号:currentChanged(int index);获取和设置当前部件(即可见部件),若没有当前部件,则索引为−1
int currentIndex() const;
void setCurrentIndex(int index)
- stackingMode:StackingMode
//获取和设置子部件的显示方式,默认为 StackOne。StackingMode 枚举取值如下:
StackingMode stackingMode() const;
void setStackingMode(StackingMode);
- //QStackedLayout::StackOne(值为 0):只有当前部件可见(默认值)
- //QStackedLayout::StackAll(值为 1):所有部件均可见,当前部件只是被提升(即当前部件被提升到其他部件的前面)
QStackedWidget 类
QStackedWidget 类是在 QStackedLayout 之上构造的个便利的部件,其使用方法与步骤和 QStackedLayout 是一样的。QStackedWidget 类的成员函数与 QStackedLayout 类也基本上是一致的,使用该类就和使用 QStackedLayout 一样
QTabBar 类
属性名 | 说明 |
---|---|
expanding | 是否扩展选项卡 |
documentMode | 是否以适合主窗口的模式呈现 |
movable | 选项卡是否可移动 |
currentIndex | 获取和设置当前选项卡 |
shape | 描述选项卡的形状 |
elideMode | 选项卡中文本的省略方式 |
count | 获取选项卡的数量 |
autoHide | 选项卡仅 1 个时是否隐藏 |
drawBase | 是否绘制 |
usesScrollButtons | 是否使用 |
tabsClosable | 是否显示选项卡上的 |
selectionBehaviorOnRemove | 当删除当前选项卡时,使用哪个选项卡作为当前选项卡 |
iconSize | 选项卡栏中的图标大小 |
changeCurrentOnDrag | 拖动选项卡时,当前选项卡是否会自动更改。 |
QTabWidget 类(选项卡部件)
- 创建一个 QTabWidget。
- 为每个选项卡创建一个页面(容器),通常为 QWidget(不要指定父部件)。
- 把子部件插入到页面部件(即容器)中。
- 使用 addTab()或 insertTab()把页面部件放入选项卡部件。
属性
属性名 | 说明 |
---|
属性名 说明 |count |获取选项卡的数量| documentMode |是否以适合文档页面的模式呈现 |movable |选项卡是否可移动 |currentIndex |获取和设置当前选项卡 |elideMode |选项卡中文本的省略方式 |tabsClosable| 是否显示选项卡上的 |iconSize |选项卡栏中的 |usesScrollButtons| 是否使用
函数
把页面部件 page 和具有文本 label 和(或)图标 icon 的选项卡添加到 QTabWidget 部件的末尾或插入到索引 index 处,并返回选项卡栏上该选项卡的 索引。
QTabWidget(QWidget* parent = Q_NULLPTR); //构造函数
int addTab(QWidget* page, const QString &label);
int addTab(QWidget* page, const QIcon &icon, const QString &label);
int insert(int index, QWidget* page, const QString &label);
int insert(int index, QWidget* page, const QIcon &icon, const QString &label);
//移除所有页面,但不删除它们。调用此函数相当于调用 removeTab()函数直到选项卡部件为空。
void clear();
//移除索引 index 处的选项卡,页面不会被删除。
void removeTab(int index);
//返回部件 w 的索引位置,若没有该部件则返回−1 ⑥、QWidget* widget(int index) const; //返回索引 index 处的页面部件。
int indexOf(QWidget* w) const;
//返回指向当前页面部件的指针。
QWidget* currentWidget() const;
//槽,把 widget 设置为当前页面(可见页面)。 ⑧、QTabBar* tabBar() const; //返回当前的
void setCurrentWidget(QWidget* widget);
//受保护的。
void setTabBar(QTabBar* tb);
QWidget* cornerWidget(Qt::Corner corner = Qt::TopRightCorner) const;
//返回角落 corner 处的小部件或 0。
void setCornerWidget(QWidget* widget, Qt::Corner corner = Qt::TopRightCorner);
- 右上角的button [外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-3Ha3xox1-1632751916586)(./pic/conerWdight.png)]
QTabWidget 类
void setTabEnabled(int index, bool enabled); //设置选项卡的启用/禁用状态,禁用状态呈现出灰色。
bool isTabEnabled(int index) const; //获取选项卡的启用/禁用状态
void setTabIcon(int index, const QIcon& icon); //设置选项卡的图标
QIcon tabIcon(int index) const; //获取选项卡的图标。
void setTabText(int index, const QString &text); //设置选项卡的文本
QString tabText(int index) const; //获取选项卡的文本。
void setTabToolTip(int index, const QString &tip); //设置选项卡的提示文本
QString tabToolTip(int index) const; //获取选项卡的提示文本。
void setTabWhatsThis(int index, const QString &text); //设置选项卡的帮助文本
QString tabWhatsThis(int index) const; //获取选项卡的帮助文本。
QTabWidget 类中的信号
void currentChanged(int index); //信号当选项卡栏上的当前选项卡发生更改时发送此信号,index 为新选项卡的索引,若没有新的索引,则为−1(比如 QTabBar 中没有选项卡)。该信号比较重要。
void tabBarClicked(int index); //信号,qt5.2
void tabBarDoubleClicked(int index); //信号,qt5.2
以上信号表示,单击或双击 index 处的选项卡时发送此信号,index 是单击选项卡的索引,若光标下没有选项卡,则为−1。
void tabCloseRequested(int index); //信号当点击选项卡上的关闭按钮时发送此信号,index 为应删除的选项卡的索引。
QSplitter 类(分离器)
QSplitter 的原理(见上图)
- QSplitter 的实现原理与 QBoxLayout 布局的原理类似,即 QSplitter把子部件以水平或垂直的方式添加到 QSplitter 中,只不过在这些子部件之间多了一条分界线 -QSplitter 类继承自 QFrame 类,也就是说该类是一个的可视部件
分界线
- 分界线的创建:分界线是由 QSplitterHandle 类实现的,QSplitter 类本身不实现分界线。因此 ,只不过这两个部件通过 Qt 的内部设计,让他们关联在一起,产生了一定的联系。
- 背景色:QSplitter 的分界线默认有可能是(因为颜色与 QSplitter 背景色相同,所以看不见),因此
- 分界线的索引:其,分界线的数量与子部件的数量一样多。