qt 5

c++风格


qtcreator必须掌握的快捷键
1.ctrl+tab切换打开的窗口
2.alt+enter在.cpp里面快速添加定义
3.ctrl+shift 修改相同变量
4.ctrl+m书签,ctrl+.转到书签
5.ctrl+e+2/3/1分栏显示
6.f4/f2/ctrl+shift+up(down)/ctrl+i
头文件
  • 自给自足原则

用户和重构工具不需要为特别场合而包含额外的头文件。

  • #define保护
#ifndef FOO_BAR_BAZ_H_
#define FOO_BAR_BAZ_H_
...
#endif // FOO_BAR_BAZ_H
  • 尽量避免前置声明

waht is 前置声明?

class Date 
{
     
    private:  
        int year, month, day;  
};  
//if want to use this class ,have two ways:
//one前置声明
class Date;  
class Task1 
{
     
    public:  
        Date getData();  
};  
//two包含头文件
#include "Date.h"  
class Task2
{
     
    public:  
        Date getData();  
};  
  • 慎用内联函数

在函数很短,可以内联,但是得保证此函数很少被调用

  • include的路径和顺序
#include <zylg.h>// find it on system first
#include "zylg.h"//find it on project first
作用域
#ifndef MYTEST_H
#define MYTEST_H
#include<iostream>
const int i=5;//内链接的特性,可以让其他的文件重新定义i(假如其他的问价include这个文件,当然也可以直接使用)
namespace zylg
{
    void s();
    namespace//让其具有内部链接性,相当于static后的一大块区域
    {
        void s1(){
  std::cout<<"my is inline namespace function,as  in static area,\n other file don`t use me\n";}
    }


};
#endif // MYTEST_H



#include<iostream>
using namespace std;
int i=9;
void s1()
{
    cout<<"how are you";
}
int main(int argc, char *argv[])
{
    s1();
   return 0;
}

1.匿名的命名空间会把空间里面的定义的东西自动放在上一级命名空间,比如上述代码可以zylg::s1(),这样保证了全局变量的名称资源(因为具有内部链接性),同时节约了命名空间数量

2.局部变量
将函数变量尽可能至于最小的作用域

3.全局变量和静态变量尽可能在控制范围内,少用

1.不要在构造函数里面调用虚函数,也不要在无法报出错误时进行可能失败的初始化.


2.不要定义隐式类型转换. 对于转换运算符和单参数构造函数, 请使用 explicit 关键字.别让int默默的就double了,explicit可以保证函数不会发生隐式转换,涉及类型转换的应该加上


3.可拷贝类型和可移动类型
如果你的类型需要, 就让它们支持拷贝 / 移动. 否则, 就把隐式产生的拷贝和移动函数禁用.

// MyClass is neither copyable nor movable.
MyClass(const MyClass&) = delete;
MyClass& operator=(const MyClass&) = delete;

4.结构体
仅当只有数据成员时使用 struct, 其它一概使用 class.


继承
使用组合 (YuleFox 注: 这一点也是 GoF 在 <> 里反复强调的) 常常比使用继承更合理. 如果使用继承的话, 定义为 public 继承.

//介绍组合模式
class component
{
   
//声明全部你所要用到的函数,在此处为虚函数,不去定义
}
class composite:public component
{
   
//实现虚函数全部
}
class left:public component
{
   
//实现个别的虚函数
}
/*
*在继承的时候,析构函数声明为虚函数,不然会发生内存泄露
*/

6.多重继承
真正需要用到多重实现继承的情况少之又少. 只在以下情况我们才允许多重继承: 最多只有一个基类是非抽象类; 其它基类都是以 Interface 为后缀的 纯接口类.


7.接口
接口是指满足特定条件的类, 这些类以 Interface 为后缀 (不强制).


8.运算符重载
除少数特定环境外, 不要重载运算符. 也不要创建用户定义字面量.


9.存取控制
将 所有 数据成员声明为 private, 除非是 static const 类型成员 (遵循 常量命名规则). 处于技术上的原因, 在使用 Google Test 时我们允许测试固件类中的数据成员为 protected.


10.声明顺序
类定义一般应以 public: 开始, 后跟 protected:, 最后是 private:. 省略空部分.

函数

1.函数参数顺序
函数的参数顺序为: 输入参数在先, 后跟输出参数.


  1. 编写简短函数,我们倾向于编写简短, 凝练的函数.

3.引用参数
所有按引用传递的参数必须加上 const.
as:void Foo(const string &in, string *out);


4.函数重载
若要使用函数重载, 则必须能让读者一看调用点就胸有成竹, 而不用花心思猜测调用的重载函数到底是哪一种. 这一规则也适用于构造函数.


5.只允许在非虚函数中使用缺省参数, 且必须保证缺省参数的值始终一致. 缺省参数与 函数重载 遵循同样的规则. 一般情况下建议使用函数重载, 尤其是在缺省函数带来的可读性提升不能弥补下文中所提到的缺点的情况下.

study for google

1.所有权与智能指针,动态分配出的对象最好有单一且固定的所有主, 并通过智能指针传递所有权.
所有权是一种登记/管理动态内存和其它资源的技术. 动态分配对象的所有主是一个对象或函数, 后者负责确保当前者无用时就自动销毁前者. 所有权有时可以共享, 此时就由最后一个所有主来负责销毁它. 甚至也可以不用共享, 在代码中直接把所有权传递给其它对象.
智能指针是一个通过重载 * 和 -> 运算符以表现得如指针一样的类. 智能指针类型被用来自动化所有权的登记工作, 来确保执行销毁义务到位. std::unique_ptr 是 C++11 新推出的一种智能指针类型, 用来表示动态分配出的对象的独一无二的所有权; 当 std::unique_ptr 离开作用域时, 对象就会被销毁. std::unique_ptr 不能被复制, 但可以把它移动(move)给新所有主. std::shared_ptr 同样表示动态分配对象的所有权, 但可以被共享, 也可以被复制; 对象的所有权由所有复制者共同拥有, 最后一个复制者被销毁时, 对象也会随着被销毁.


2.cppplint
使用 cpplint.py 检查风格错误.

else study
1.所有按引用传递的参数必须加上const.
2.只在定义移动构造函数与移动赋值操作时使用右值引用. 不要使std::forward.
3.若要用好函数重载,最好能让读者一看调用点(call site)就胸有成竹,不用花心思猜测调用的重载函数到底是哪一种。该规则适用于构造函数。
4.我们不允许使用缺省函数参数,少数极端情况除外。尽可能改用函数重载。
5.我们不允许使用变长数组alloca().
6.我们允许合理的使用友元类及友元函数.
7.我们不使用 C++ 异常.
8.我们禁止使用 RTTI.在运行时判断类型通常意味着设计问题. 如果你需要在运行期间确定一个对象的类型, 这通常说明你需要考虑重新设计你的类
9.使用 C++ 的类型转换, 如 static_cast<>(). 不要使用 int y = (int)x 或 int y = int(x) 等转换方式;
10.只在记录日志时使用流.不要使用流,除非是日志接口需要. 使用 printf 之类的代替.使用流还有很多利弊, 但代码一致性胜过一切. 不要在代码中使用流.
11.对于迭代器和其他模板对象使用前缀形式 (++i) 的自增, 自减运算符.
12.我们强烈建议你在任何可能的情况下都要使用 const. 此外有时改用 C++11 推出的 constexpr 更好。
13.整形int16_t.如果您的变量可能不小于 2^31 (2GiB), 就用 64 位变量比如 int64_t. 此外要留意,哪怕您的值并不会超出 int 所能够表示的范围,在计算过程中也可能会溢出。所以拿不准时,干脆用更大的类型。
14.可移植性,代码应该对 64 位和 32 位系统友好. 处理打印, 比较, 结构体对齐时应切记
15.使用宏时要非常谨慎, 尽量以内联函数, 枚举和常量代替之.
16.nullptr 和 NULL,整数用 0, 实数用 0.0, 指针用 nullptr 或 NULL, 字符 (串) 用 '\0'.
17.尽可能用 sizeof(varname) 代替 sizeof(type).
18.auto 绕过烦琐的类型名,只要可读性好就继续用,别用在局部变量之外的地方。
19.适当使用 lambda 表达式。别用默认 lambda 捕获,所有捕获都要显式写出来。
20.只使用 Boost 中被认可的库.
命名规则

函数命名, 变量命名, 文件命名要有描述性; 少用缩写.

//文件命名:文件名要全部小写, 可以包含下划线 (_) 或连字符 (-), 依照项目的约定. 如果没有约定, 那么 “_” 更好.
//类型名命名:类型名称的每个单词首字母均大写, 不包含下划线
//变量名:变量 (包括函数参数) 和数据成员名一律小写, 单词之间用下划线连接,类变量以下划线结尾
//常量名:声明为 constexpr 或 const 的变量, 或在程序运行期间其值始终保持不变的, 命名时以 “k” 开头, 大小写混合
//函数名;规函数使用大小写混合, 取值和设值函数则要求与变量名匹配
//命名空间:命名空间以小写字母命名. 最高级命名空间的名字取决于项目名称
//枚举;枚举的命名应当和 常量 或 宏 一致: kEnumName 或是 ENUM_NAME.
注释

使用 // 或 /* */, 统一就好.


在每一个文件开头加入版权公告.描述了该文件的内容


每个类的定义都要附带一份注释, 描述类的功能和用法, 除非它的功能相当明显.


通常变量名本身足以很好说明变量用途. 某些情况下, 也需要额外的注释说明.

//注:注释别写一些谁看函数都能看出来的废话,不如不写
格式
//1.每一行代码字符数不超过 80.
//2.尽量不使用非 ASCII 字符, 使用时必须使用 UTF-8 编码.
//3.倾向于不在圆括号内使用空格. 关键字 if 和 else 另起一行.
//4.switch 语句可以使用大括号分段, 以表明 cases 之间不是连在一起的. 在单语句循环里, 括号可用可不用. 空循环体应使用 {} 或 continue.
//5.不要在 return 表达式里加上非必须的圆括号.
//6.访问控制块的声明依次序是 //7.public:, protected:, private:, 每个都缩进 1 个空格.
//8.命名空间内容不缩进.

pro文件详解

TAMPLATE

描述为建立目标文件而采用的模板,即生成何种makefile文件
a.app(应用程序)
b.lib(库文件)
c.subdirs(子工程)
d.vcapp(仅用于windows的应用程序)
e.vclib

HEADERS

所有头文件列表

SOURCES

源文件列表

FORMS / INTERFACES

ui文件列表

LEXSOURCES

lex源文件列表

YACCSOURCES

yacc源文件列表

TARGET

可执行应用程序名称

DESTDIR

放置可执行目标的目录

DEFINES

应用程序所需的额外的预处理程序定义的列表。

INCLUDEPATH

应用程序所需的额外的包含路径的列表(include文件路径列表)。

DEPENDPATH

应用程序所依赖的搜索路径(描述了建立应用程序所依赖的其他文件所在的路 径)。

VPATH

寻找补充文件的搜索路径。

DEF_FILE

只有Windows需要:应用程序所要连接的.def文件。

C_FILE

只有Windows需要:应用程序的资源文件。

RES_FILE

只有Windows需要:应用程序所要连接的资源文件。

CONFIG变量

配置变量指定了编译器所要使用的选项和所需要被连接的库。配置变量中可以添加任何东西,但只有下面这些选项可以被qmake识别。

下面这些选项控制着使用哪些编译器标志:

release - 应用程序将以release模式连编。如果“debug”被指定,它将被忽略。

debug - 应用程序将以debug模式连编。

warn_on - 编译器会输出尽可能多的警告信息。如果“warn_off”被指定,它将被忽略。

warn_off - 编译器会输出尽可能少的警告信息。
qt - 应用程序是一个Qt应用程序,并且Qt库将会被连接。

thread - 应用程序是一个多线程应用程序。

x11 - 应用程序是一个X11应用程序或库。

windows - 只用于“app”模板:应用程序是一个Windows下的窗口应用程序。

console - 只用于“app”模板:应用程序是一个Windows下的控制台应用程序。

dll - 只用于“lib”模板:库是一个共享库(dll)。

staticlib - 只用于“lib”模板:库是一个静态库。

plugin - 只用于“lib”模板:库是一个插件,这将会使dll选项生效。

因为还用不到高级的,那这些就够用了
资源文件

<RCC>
    <qresource prefix="/image">
        <file>wz.jpg</file>
        <file>wz2.jpg</file>
    </qresource>
    <qresource prefix="/pictrue">
        <file>wz.jpg</file>
        <file>resourcefile.qrc</file>
        <file>wz2.jpg</file>
    </qresource>
</RCC>
/*
*Add New File -> Qt Resource File
*列出的资源文件必须位于 .qrc 文件所在目录或其子目录。
*/
//use ways
QMovie *movie =new QMovie(":/image/wz.jpg");

元对象系统


元对象系统提供了信号与槽机制

1.QObject类,为objects提供了一个可以利用元对象系统的基类。
2.Q_OBJECT宏: 在类的私有部分声明这个宏可以启用元对象特性,例如:动态属性、信号与槽。
3.Meta-Object编译器(moc): 为每个QObject子类生成必要的代码来实现元对象特性。
moc工具会读取C++源文件,如果发现有包含Q_OBJECT宏的类声明,就生成另外一个包含这些类的元对象代码的C++源文件。生成的源文件要么在类源文件里用#include包含,或者(更常见)与类的实现代码直接进行编译连接。

QObject::metaObject()返回类关联的meta-object对象。

QMetaObject::className()在运行时以字符串的形式返回类名,无需C++编译器提供运行时类别信息(RTTI)的支持。

QObject::inherits()返回一个对象是否是QObject继承树上一个类的实例。

QObject::tr()和QObject::trUtf8()提供国际化支持,将字符串翻译成指定的语言。

QObject::setProperty()和QObject::property()通过名称动态设置和获取属性。

QMetaObject::newInstance()构造类的一个新实例。
qobject_cast()动态转换QObject类的类型。qobject_cast()函数和标准C++的dynamic_cast()功能类似

    QObject *obj=new mywidget;
    QWidget  *wid=qobject_cast<QWidget *>(obj);
    wid->setObjectName("widget");
    mywidget *myw=qobject_cast<mywidget *>(wid);
属性

1.要声明一个属性,在继承QObject的类中使用Q_PROPERTY()宏


2.一个属性的行为就像一个类的数据成员,但它有通过元对象系统访问的附加功能。

声明属性需求
  • 如果MEMBER关键字没有被指定,则一个READ访问函数是必须的。它被用来读取属性值。理想的情况下,一个const函数用于此目的,并且它必须返回的是属性类型或const引用。比如:QWidget::focus是一个只读属性,通过READ函数QWidget::hasFocus()访问。

  • 一个WRITE访问函数是可选的,用于设置属性的值。它必须返回void并且只能接受一个参数,属性的类型是类型指针或引用,例如:QWidget::enabled具有WRITE函数QWidget::setEnabled()。只读属性不需要WRITE函数,例如:QWidget::focus没有WRITE函数。

  • 如果READ访问函数没有被指定,则MEMBER变量关联是必须的。这使得给定的成员变量可读和可写,而不需要创建READ和WRITE访问函数。如果需要控制变量访问,仍然可以使用READ和WRITE函数而不仅仅是MEMBER(但别同时使用)。

  • 一个RESET函数是可选的,用于将属性设置为上下文指定的默认值。例如:QWidget::cursor有READ和WRITE函数QWidget::cursor()和QWidget::setCursor(),同时也有一个RESET函数QWidget::unsetCursor(),因为没有可用的QWidget::setCursor()调用可以确定的将cursor属性重置为上下文默认的值。RESET函数必须返回void类型,并且不带任何参数。

  • 一个NOTIFY信号是可选的。如果定义了NOTIFY,则需要在类中指定一个已存在的信号,该信号在属性值发生改变时发射。与MEMBER变量相关的NOTIFY信号必须有零个或一个参数,而且必须与属性的类型相同。参数保存的是属性的新值。NOTIFY信号应该仅当属性值真正的发生变化时发射,以避免被QML重新评估。例如:当需要一个没有显式setter的MEMBER属性时,Qt会自动发射信号。

  • 一个REVISION数字是可选的。如果包含了该关键字,它定义了属性并且通知信号被特定版本的API使用(通常是QML);如果没有包含,它默认为0。

  • DESIGNABLE属性指定了该属性在GUI设计器(例如:Qt Designer)里的编辑器中是否可见。大多数的属性是DESIGNABLE (默认为true)。除了true或false,你还可以指定boolean成员函数。

  • SCRIPTABLE属性表明这个属性是否可以被一个脚本引擎操作(默认是true)。除了true或false,你还可以指定boolean成员函数。

  • STORED属性表明了该属性是否是独立存在的还是依赖于其它属性。它也表明在保存对象状态时,是否必须保存此属性的值。大多数属性是STORED(默认为true)。但是例如:QWidget::minmunWidth()的STROED为false,因为它的值从QWidget::minimumSize()(类型为QSize)中的width部分取得。

  • USER属性指定了属性是否被设计为用户可见和可编辑的。通常情况下,每一个类只有一个USER属性(默认为false)。例如: QAbstractButton::checked是(checkable)buttons的用户可修改属性。注意:QItemDelegate获取和设置widget的USER属性。

  • CONSTANT属性的出现表明属性是一个常量值。对于给定的object实例,常量属性的READ函数在每次被调用时必须返回相同的值。对于不同的object实例该常量值可能会不同。一个常量属性不能具有WRITE函数或NOYIFY信号。

  • FINAL属性的出现表明属性不能被派生类所重写。有些情况下,这可以用于效率优化,但不能被moc强制执行。必须注意不能覆盖一个FINAL属性。

  • 属性类型可以是QVariant支持的任何类型,或者是用户定义的类型。在这个例子中,类QDate被看作是一个用户定义的类型。

Q_PROPERTY(bool focus READ hasFocus)
Q_PROPERTY(bool enabled READ isEnabled WRITE setEnabled)
Q_PROPERTY(QCursor cursor READ cursor WRITE setCursor RESET unsetCursor)
   Q_PROPERTY(QColor color MEMBER m_color NOTIFY colorChanged)
    Q_PROPERTY(qreal spacing MEMBER m_spacing NOTIFY spacingChanged)
    Q_PROPERTY(QString text MEMBER m_text NOTIFY textChanged)
    ...
signals:
    void colorChanged();
    void spacingChanged();
    void textChanged(const QString &newText);

private:
    QColor  m_color;
    qreal   m_spacing;
    QString m_text;

一个属性可以使用常规函数QObject::property()和QObject::setProperty()进行读写,除了属性的名字,不用知道属性所在类的任何细节。

QPushButton *button = new QPushButton;
QObject *object = button;

button->setDown(true);
object->setProperty("down", true);
事件

在Qt中,事件就是对象,派生自QEvent抽象类

事件的运行过程

当一个事件发生时Qt会构造一个事件的对象,它识别事件类型,将事件发送给特定的对象,而后特定的对象将会返回特定的bool


事件机制
bool QCoreApplication::notify(QObject * receiver, QEvent * event) [virtual]
发送事件给接收者,接收者处理并返回状态.


事件处理陈程序
相当于一个虚函数,你也可以自己重写虚函数


事件过滤器
所谓事件过滤就是提前截获发往某个对象的所有消息,根据需要屏蔽掉某一些,或者对某些消息提前进行些处理,其他的事件处理将不会接收到该事件.

//eventfilter.cpp
#include "eventfilter.h"
#include <QEvent>
#include <QKeyEvent>

bool eventfilter::eventFilter(QObject *to, QEvent *event)//event filter(write number only)
{
    static QString digits = QString("1234567890");
    if(event->type() == QEvent::KeyPress)
    {
        QKeyEvent *keyEvent = static_cast<QKeyEvent*> (event);
        if( digits.indexOf(keyEvent->text()) != -1 )
        {
            return false;
        }
        return true;
    }
    return QObject::eventFilter(to, event);
}


//main.cpp
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    mywidget *myw=new mywidget;         //display widget
    eventfilter *eve=new eventfilter;   //evevt filter,it let textbroser write number only
    QTextEdit *textbrowser=new QTextEdit;
    textbrowser->installEventFilter(eve);//use filetr
    QVBoxLayout *layout=new QVBoxLayout(myw);
    layout->addWidget(textbrowser);
    myw->show();
    return a.exec();
}

发送事件
使用notify()函数直接给receiver发送事件。
postEvent(QObject* receiver, QEvent* event)
向事件队列中添加receiver和event。
简单说,sendEvent使用的是同步处理事件,postEvent使用的异步处理事件

QCoreApplication::sendEvent()
QCoreApplication::postEvent()

这里可以看到事件是如何处理的:
先送入Application的事件过滤器,看看是否在事件过滤器中处理
再查看receiver是否有此事件的过滤器
最后,将事件送入receiver的event接口。

常见的事件类型

QResizeEvent、QPaintEvent、QMouseEvent、QKeyEvent、QCloseEvent。

介绍

信号和插槽用于对象之间的通信。
在GUI编程中,当我们更改一个小部件时,我们经常需要通知另一个小部件。更一般地说,我们希望任何类型的对象能够彼此通信。例如,如果用户单击“ 关闭”按钮,我们可能希望调用窗口的close()函数。

运行机制

一个对象发出信号,另一个对象给出自己的插槽处理,其中slot的参数个数可少于sinal的参数个数,当然参数可以使用默认参数,as:change(int i=0);

#include <QObject>
class Counter : public QObject
{
    Q_OBJECT
public:
    Counter() { m_value = 0; }
    int value() const { return m_value; }
public slots:
void setValue(int value)
    {
        if (value != m_value)
         {
            m_value = value;
            //===========定义函数,发生将会发射sinal=======
            emit valueChanged(value);
         }
    }  
signals:
    void valueChanged(int newValue,int oldvalue);
private:
    int m_value;
};
Counter a, b;
    QObject::connect(&a, SIGNAL(valueChanged(int)),
                     &b, SLOT(setValue(int)));
    a.setValue(12);     // a.value() == 12, b.value() == 12
    b.setValue(48);     // a.value() == 12, b.value() == 48
   QObject::connect(&ac, SIGNAL(valueChanged(int,int)),&bc, SLOT(setValue(int)));//can use a`s arguments bigger b`s arguments
connect(buttonGroup, QOverload<int, bool>::of(&QButtonGroup::buttonToggled),
    [=](int id, bool checked){ /* ... */ });
//不用signal和slot的connect的写法,了解一下

QTimer


QTimer提供单词计时器和重复计时器
slots

void start([int msec])
void stop()

sinals

void timeout()

虚函数

virtual void timerEvent(QTimerEvent *e) override

class test : public QObject
{
    Q_OBJECT
public:
    test()
    {
        //intervals 0.5 seconds to say hello world
        QTimer *timer = new QTimer();
        connect(timer, &QTimer::timeout,[]{qDebug()<<"hello world";});
        timer->start(1000);
    }
};

//run
int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    test t1;
    return a.exec();
}
   QTimer::singleShot(2000,[]{qDebug()<<"hello world";} );//
对象树销毁

当创建一个object对象时,如果使用了其他对象作为父对象,如果父对象被销毁,其被销毁.

构造和销毁的顺序

和c++一样,基类构造,子类构造,子类析构,基类析构,,但是在qt中,父类销毁了也就意味子类被销毁,so

int main()
{
    QPushButton quit("Quit");
    QWidget window;
    quit.setParent(&window);
    ...
}//have error
//如果动态创建就不会出现这些个问题,new,这里父窗口的析构函数将会最先被调用

int main()
{
    QWidget window;
    QPushButton quit("Quit", &window);
    ...
}//这里是正常的,其实吧这问题不了解也行,只要知道父销毁,子就被销毁就好

QWidgets

所有用户界面对象的基类。
Header: #include
qmake: QT += widgets

内容 函数名
窗口函数 show(),hide(),raise()//顶层,lower()//底层,close()
顶层窗口 windowModified, windowTitle, windowIcon, isActiveWindow, activateWindow(), minimized, showMinimized(), maximized, showMaximized(), fullScreen, showFullScreen(), showNormal().
窗口内容 update(), repaint(), scroll().//update()不会立即进行重绘事件,有一个事件循环,不会像repaint()那样发生闪烁
常规 pos, x(), y(), rect, size, width(), height(), move(), resize(), sizePolicy, sizeHint(), minimumSizeHint(), updateGeometry(), layout(), frameGeometry, geometry, childrenRect, childrenRegion, adjustSize(), mapFromGlobal(), mapToGlobal(), mapFromParent(), mapToParent(), maximumSize, minimumSize, sizeIncrement, baseSize, setFixedSize()
模式 visible, isVisibleTo(), enabled, isEnabledTo(), modal, isWindow(), mouseTracking, updatesEnabled, visibleRegion().
style style(), setStyle(), styleSheet, cursor, font, palette, backgroundRole(), setBackgroundRole(), fontInfo(), fontMetrics().
焦点 focus, focusPolicy, setFocus(), clearFocus(), setTabOrder(), setFocusProxy(), focusNextChild(), focusPreviousChild().
事件 event(), mousePressEvent(), mouseReleaseEvent(), mouseDoubleClickEvent(), mouseMoveEvent(), keyPressEvent(), keyReleaseEvent(), focusInEvent(), focusOutEvent(), wheelEvent(), enterEvent(), leaveEvent(), paintEvent(), moveEvent(), resizeEvent(), closeEvent(), dragEnterEvent(), dragMoveEvent(), dragLeaveEvent(), dropEvent(), childEvent(), showEvent(), hideEvent(), customEvent(). changeEvent()
系统函数 parentWidget(), window(), setParent(), winId(), find(), metric().
提示 setToolTip(), setWhatsThis()
slots
bool    close()
void    hide()
void    lower()
void    raise()
void    repaint()
void    setDisabled(bool disable)
void    setEnabled(bool)
void    setFocus()
void    setHidden(bool hidden)
void    setStyleSheet(const QString &styleSheet)
virtual void    setVisible(
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Buildroot是一个用于嵌入式Linux系统构建的工具集,而Qt5是一个功能强大的跨平台应用程序开发框架。在使用Buildroot构建嵌入式系统时,可以选择将Qt5集成到系统中。 首先,需要在Buildroot的配置文件中启用Qt5的支持。通过运行make menuconfig命令,打开配置菜单,选择Target packages -> Graphics libraries and applications -> Qt5,然后选择所需的Qt5版本。保存配置后,再次运行make命令进行编译。 在Buildroot的构建过程中,会下载所选Qt5版本的源码并自动进行编译。编译完成后,可以通过设置环境变量来指定Qt5的安装路径,以便后续的应用程序开发和部署。 一旦Qt5被成功集成到Buildroot生成的嵌入式系统中,就可以使用Qt5开发工具来创建和编译应用程序。Qt5提供了丰富的库和组件,可以轻松开发图形界面、网络通信、数据库访问等功能。通过Qt Creator等集成开发环境,可以进行可视化的应用程序设计和编码工作。 最后,将使用Qt5开发的应用程序编译链接到Buildroot生成的嵌入式系统中,以确保应用程序能够在目标硬件上正确运行。可以使用Buildroot提供的工具链和根文件系统进行部署和测试。 总之,通过使用Buildroot集成Qt5,可以快速搭建嵌入式系统,并利用Qt5轻松开发出功能丰富的应用程序。 ### 回答2: Buildroot是一个嵌入式Linux系统的开源工具,它能够帮助开发者构建轻量级、定制化的Linux发行版。而Qt5是一个跨平台的应用程序开发框架,它提供了丰富的工具和库,方便开发者进行图形界面和应用程序的开发。 Buildroot与Qt5的结合,可以为嵌入式系统开发提供更强大的支持和便利性。通过Buildroot,我们可以轻松地集成Qt5及其相关的库和工具到目标系统中。首先,我们需要在Buildroot的配置文件中选择Qt5的编译选项,然后配置相关的构建参数。接下来,Buildroot会自动下载所需的源代码并进行编译。 在编译过程中,我们可以根据需要选择要集成的Qt5组件,包括Qt GUI、Qt网络、Qt多媒体等等。同时,Buildroot还提供了一套完整的配置接口,可以帮助我们灵活地进行定制。我们可以选择编译Qt5的静态库或动态库,也可以选择是否开启Qt的一些高级功能,如WebEngine模块等。 最后,通过Buildroot构建的嵌入式Linux系统中,我们可以直接使用Qt5提供的工具和库进行应用程序的开发。我们可以使用Qt Creator这样的集成开发环境来编写和调试应用程序,也可以使用Qt Quick来开发漂亮的图形界面。 综上所述,Buildroot与Qt5的结合能够极大地简化嵌入式Linux系统的构建和应用程序的开发过程。它们为嵌入式开发者提供了更高效、更灵活的工具和环境,帮助开发者更轻松地实现定制化的嵌入式系统。 ### 回答3: Buildroot是一个用于嵌入式系统中构建根文件系统的工具。它可以帮助我们从源代码构建整个嵌入式系统,包括内核、库和应用程序等。 Qt是一种跨平台的应用程序开发框架,它具有丰富的图形界面和多媒体功能。Qt可以用于开发桌面应用程序、嵌入式系统以及移动应用。 将Buildroot和Qt5结合使用,可以方便地构建一个包含Qt5框架的嵌入式系统。 首先,我们需要为Buildroot配置一个Qt5的构建环境。在Buildroot的配置菜单中,选择相应的配置选项以启用Qt5的支持。 然后,我们需要提供Qt5的源代码。在Buildroot的配置菜单中,指定Qt5的源代码路径,并选择所需的版本。 接下来,进行构建。执行构建命令后,Buildroot会下载所需的软件包、解压源代码,并进行依赖项的解析和编译。在这个过程中,Qt5将被编译并集成到最终的根文件系统中。 构建完成后,我们可以将生成的根文件系统烧录到目标设备中。在设备上运行系统后,我们就可以使用Qt5框架开发和运行应用程序了。 在使用Buildroot和Qt5构建嵌入式系统时,需要注意以下几点: 1. 系统需求:根据目标设备的硬件平台选择合适的Buildroot配置和Qt5版本。确保系统具备足够的硬件资源来运行Qt5应用程序。 2. 依赖项:在使用Qt5之前,需要确保系统已经正确安装了所需的依赖项。Buildroot会帮助我们自动解决依赖关系,但我们需要在配置过程中指定正确的选项。 3. 构建时间:由于Qt5是一个庞大的框架,构建时间可能会较长。我们需要根据系统性能和需求进行相应的调整和优化。 总而言之,通过使用Buildroot和Qt5,我们可以方便地构建嵌入式系统并集成Qt5的功能。这能为嵌入式应用程序开发提供一个简单、快速和高效的方法。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值