QT基础及对象树的认识
引例
图形化创建
标签

若直接在.ui文件里拖动控件修改,那么.ui文件会被修改,可以看到右上角原本只有Widget默认的空间,现在多了一个Label控件,在.ui文件里,也多了一段代码:
<widget class="QLabel" name="label"><property name="geometry"><rect><x>240</x><y>230</y><width>161</width><height>101</height></rect></property><property name="text"><string>helloworld</string></property></widget>
运行的结果如下:

在这个.ui文件里创建的这一段代码后,在运行的时候会构建ui_widget.h文件,会影响构建的ui_widget.h文件内容。

可以看到在创建的代码里有这么几行:
label = new QLabel(Widget);//创建一个label对象
label->setObjectName("label");//设置label对象的名称为label
label->setGeometry(QRect(240, 230, 161, 101));//设置label的属性
文本编辑框
文本编辑框有分为单行文本编辑框和多行文本编辑框,同样的,我们可以通过图形化或者代码两种方式创建文本编辑框,我们这边涉及到的是单行文本编辑框,所以我们选择Line Edit,拖动这个控件到界面上,就可以编辑了

<widget class="QLineEdit" name="lineEdit"><property name="geometry"><rect><x>300</x><y>280</y><width>113</width><height>25</height></rect></property><property name="text"><string>hello world</string></property></widget></widget><resources/><connections/>
这样就创建一个文本框了

按钮
我们平常使用的按钮是pushbutton

执行完后是这样:

由于我们没有绑定需要的函数,所以点击这个按钮并不会有任何反应,这就涉及到信号和槽了。
代码创建
标签
在widget.cpp里创建QLabel对象,可以在栈上创建,也可以在堆上创建,但QT中一般是在栈上创建的,在创建的时候一般会为这个控件对象指定一个父对象的this指针,当前Label对应的这个this指针指向一个Widget对象。
QLabel* label=new QLabel(this);
//QLabel* label=new QLabel;
//QLabel label(this);
创建完QLabel对象后,可以对这个控件设置文本内容,可以看到这里面的参数不是标准库的string,而是QT自己封装的QString,QString内部对字符编码做了处理,但string没有。

Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLabel* label=new QLabel(this);//我们new的这个对象不需要手动释放label->setText("hello world");
}
运行完之后可以看到

文本编辑框
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);QLineEdit* line=new QLineEdit(this);line->setText("hello world");
}
最后执行代码的时候输出:

按钮
点击这个按钮,可以切换按钮的文本内容
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);// QLineEdit* line=new QLineEdit(this);// line->setText("hello world");button=new QPushButton(this);button->setText("hello world");connect(button,&QPushButton::clicked,this,&Widget::HandlerClick);
}void Widget::HandlerClick()
{if(button->text()==QString("hello world")){button->setText("world hello");}else{button->setText("hello world");}
}


如果要在图形化界面实现,那么就需要关注到ui文件里ObjectName这个变量,此时这个按钮对象就是QT自动生成的,作为ui对象的一个成员变量了
对象树
在引例中,我们new了一个QLabel对象,但我们不需要手动释放,因为我们这里涉及到了一个概念----对象树,这个对象树是一个N叉树,把所有的对象组织起来了。
如果我们需要查看这个对象的生命周期,可以用一个自定义对象来观察,重写控件中的任何功能:
MyLabel::MyLabel(QWidget *parent):QLabel(parent)
{}MyLabel::~MyLabel()
{std::cout<<"MyLabel 被销毁"<<std::endl;
}
Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//QLabel* label=new QLabel(this);MyLabel* label=new MyLabel(this);label->setText("hello world");
}Widget::~Widget()
{delete ui;
}
在我们执行这个代码的时候,我们会发现控制台什么都没有输出:

而在我们关闭窗口的时候,控制台就输出了对应的析构函数信息,说明我们创建的对象被正确析构了:

但我们会发现在输出信息的时候,并不是我们定义的“MyLabel 被销毁”,而是一个乱码“MyLabel 琚攢姣”,这就涉及到QT里的乱码问题了,目前主流的字符集是GBK和UTF-8,在GBK字符集里,一个汉字占2个字节,在UTF-8字符集里,表示一个符号使用的字节数是有变化的,2-4个字节,一个汉字一般是3个字节,如果当前文件是使用A编码,但解码的时候是使用B编码,那么就会出现乱码问题。
可以在文件另存为里面查看到当前文件的编码方式,如果当前文件显示的是ANSI,那么就是GBK编码,如果显示的是UTF-8,那么就是utf8编码。

但我们要处理乱码问题,就需要统一编码方式,文本的编码格式和终端的编码方式都不太好改,QT中提供了一个qDebug工具,可以打印日志输出调试信息。
MyLabel::~MyLabel()
{//std::cout<<"MyLabel 被销毁"<<std::endl;qDebug()<<"MyLabel 被销毁";
}
这样,就不会出现乱码问题了,而且qDebug可以一键关闭日志,不输出这些调试信息。

