Qt——基础与容器类

信号与槽

首先,信号与槽是Qt的基础,信号(Signal)就是触发情况下发出去的事件,槽(Slot)则是信号接收方,即对信号响应的函数。同C++一样,有public、 private、protected 的类状态。

信号与槽的关联:

QObject::connect(sender,SIGNAL(signal()),reciever,SLOT(slot()));
或者
connect(sender,SIGNAL(signal()),reciever,SLOT(slot()));

sender 表示信号发送方,比如一些控件,push button被点击,后会发送一个clicked()信号
signal() 表示信号,slot()表示槽函数。
reciever 表示信号的接受方,比如在使用 this 指针,就是在本界面内的 slot 函数,也表示所在界面内的响应槽函数。
实例:

//**************在 .h 中的 widget 类中*********//
#ifndef WIDGET_H
#define WIDGET_H

#include 

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = nullptr);
    ~Widget();
    
private slots:
    void pushbutton_event();
  
private:
    Ui::Widget *ui;
};
#endif // WIDGET_H

//**************在Cpp文件中*************//
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    QObject::connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(slot()));//关联操作
}

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

void Widget::pushbutton_event()//槽函数
{
    ui->label->setText("pushbutton 被按下"); 
}
void Widget::on_pushButton_clicked()//这样做是从gui界面直接转到的槽,就不需要在.h中进行了
{
    ui->label->setText("pushbutton 被按下222");
}

字符串类 QString 类

1、常见操作

 QString str1 = "welcome";
 str1.append("to");
    
 QString str2;
 str2.sprintf("%s","you");
    
 QString str3;
 str3 =QString("%1 was bron in %2").arg("John").arg(1998);

    QString str4 = "welcome";
    QString str5 = "to";
    str4.insert(7,str5); //在前面位置前,插入字符串
    qDebug()<<str4;

    str4.prepend(str5); //在str4 字符串的开头插入字符串
    qDebug()<<str4;

    str4.replace("we",str5); //使用 str5 字符串代替 str4 的指定字符
    qDebug()<<str4;

    QString str6 = " welco \t mm     ";
    qDebug()<<str6.trimmed();//去掉字符串两端的空白字符

输出:
“welcometo”
“towelcometo”
“totolcometo”
“welco \t mm”
“welco mm”

2、查询字符串数据

 /****查询字符串数据*****/
    QString str8 = "welcome to you!";
    qDebug()<<str8.startsWith("welcome",Qt::CaseSensitive);//判断字符串的开头是不是参数一,参数二是多大小写敏感(默认是敏感的),返回bool
    qDebug()<<str8.startsWith("you",Qt::CaseInsensitive);//
    qDebug()<<str8.endsWith("you!",Qt::CaseSensitive);//判断结尾字符
    qDebug()<<str8.contains("to",Qt::CaseSensitive);//判断“to”字符在str8中出现过没有,返回bool

输出:
true
false
true
true

3、字符串的转换

  /*******字符串的转换***********/
    QString str9 = "125";
    QString str10 = "0xab";
    bool ok;
    int hex = str9.toInt(&ok,16);//参数1用于判断转换是否成功,参数2指定转换的类型,16即是 十六进制,基数为16
    int dec = str9.toInt(&ok,10);//十进制,默认也是十进制,基数为10
    int dec2 = str10.toInt(&ok,0);//二进制转整形,基数为0
    //toDouble(),toFloat(),toLong(),toLongLong(),一样的
    qDebug()<<hex<<" "<<dec<<" "<<dec2;

    QByteArray ba1 = str9.toLatin1();//返回一个Latin1-1(ISO8859-1)编码的8位字符串,这个用于在进行串口传输数据时,需要进行此种转换才行
    QByteArray ba2 = str9.toUtf8();//返回一个utf-8编码的字符串(utf-8是ASCII码的超集,它支持真个Unicode子集)
    QByteArray ba3 = str9.toLocal8Bit();//返回一个系统本地(locale)编码的8位字符串
    qDebug()<<ba1<<" "<<ba1.data()<<" "<<ba2 <<" "<<ba3;

输出:
293 125 171
“125” 125 “125” “125”

容器类

容器类1:QList类 QLinkedList类 QVector类

  //QList类
    QList<QString> list;
    {
        QString str("welcome to you!");
        list<<str;//赋值
    }//限制作用域
    qDebug()<<list;
QLinkedList类

属于链式列表,以非连续的内存快保存数据,且该类型不能用下表访问,只能用迭代器访问
面对很大的列表进行插入操作时,QLinkedList类的效率要比QList高很多。

QVector类

注意:在一个QVector的前部或者中间位置进行插入操作的速度是很慢的,原因是这样的操作的将会当值内存中的大量数据被移动。
QVector 是可以通过下标进行访问数据的,也可以使用迭代器访问。

Java风格迭代器遍历容器

下面以QList为例,其他类型的使用一致。

对于每一个容器类,Qt提供了类型的 Java 风格迭代器数据类型,即 只读迭代器类 和 读写迭代器类 相比 STL 风格迭代器,Java 风格的使用更加方便,但是存在轻微的性能消耗。
注意:Java 风格的迭代点 位于 列表元素项 之间,要么在第一个数据前,要么在两个相邻数据项之间,要么在最后一个数据的后面

/*******Java 风格 只读迭代器**********/

    QList<int> list_int;
    {
        list_int<<1<<2<<3<<4;
    }
    QListIterator<int> i(list_int);//以该 list_int 为遍历对象,初始化一个迭代器对象i,此时迭代点位于 list_int 列表第一个数据项的前面,即QListIterator属于向后遍历的函数
    for(;i.hasNext();) //使用 hasNext() 函数检查当前迭代点的后面是否存在数据项
    {
        qDebug()<<i.next();// next() 函数 是使迭代点跳过其后面的数据项,即此时迭代点位于第一个数据项和第二个数据项之间,并返回跳过的数据
    }

    i.toBack();//将迭代点移动到最后一个数据项的后面

    for(;i.hasPrevious();)//检查当前迭代点的前面是否存在数据项,与hasNext()相对
    {
        qDebug()<<i.previous();//previous() 函数 是使迭代点跳过其前面的数据项,即此时迭代点位于倒数第一个数据项和倒数第二个数据项之间,并返回跳过的数据
    }

    i.toFront();//将迭代点移动到第一个数据项的前面

    qDebug()<<i.peekNext();//返回迭代点后的一个数据项,但是不移动迭代点

    qDebug()<<i.peekPrevious();//返回迭代点前的一个数据项,但是不移动迭代点,位于第一个数据前,返回的该数据前的数据就是列表的最后一项(轮回型)

    if(i.findNext(3))//向后 逐个遍历检查时候存在数据项为3的。返回bool
    {
        qDebug()<<"存在3";
    }
    else if (i.findPrevious(2))//向前 逐个遍历检查时候存在数据项为3的。返回bool
    {
        qDebug()<<"存在2";
    }

 /*******Java 风格 读写迭代器**********/
    QList<int> list_int_0;

    QMutableListIterator<int> n(list_int_0);//以该 list_int_0 为读写对象,创建一个读写迭代器n

    for(int j=0;j<10;j++)
    {
        n.insert(j);// insert() 函数 插入数据到list_int_0;
    }
    for(n.toFront();n.hasNext();)//初始迭代点到列表开头
    {
        qDebug()<<n.next();
    }
    for(n.toBack();n.hasPrevious();)
    {
        if(n.previous()%2==0) //需要注意的是 previous() 的操作中涉及到了使迭代点向前移动一次
        {
            n.remove();//删除迭代点 前 的数据项
        }
        else
        {
            n.setValue(n.peekNext()*10);//重新设定迭代点 前 的数据
        }
    }
    for(n.toFront();n.hasNext();)
    {
        qDebug()<<n.next();
    }

STL 风格 只读与读写迭代器

Qt 同样为STL 提供了只读和读写的迭代器,需要注意的是 只读迭代器 要比 读写迭代器 运行速度快很多,故尽量多使用只读。
与 Java 风格的区别在于 STL 的迭代点事指向数据项自身的

QList<int> list_int_1;
    for(int i=0;i<10;i++)
    {
        list_int_1.insert(list_int_1.end(),i);// 从列表的最后项开始插入,insert(),指定 插入的位置 与 待插入的值
    }

    QList<int>::Iterator m; //定义个读写迭代器,注意这是个指针

    for( m = list_int_1.begin() ; m != list_int_1.end() ; ++m )
    {
        qDebug()<<(*m);// 获取 m 迭代指针所指的内容
        *m = (*m)*10;
    }

    QList<int>::const_iterator d;//定义一个只读迭代器,同样属于指针

    for(d = list_int_1.constBegin();d != list_int_1.constEnd(); ++d)
    {
        qDebug()<<*d;
    }

容器类2:QMap类 和 QHash类

QMap类

QMap 提供了一个从类型为 Key 的键 到类型为 T 的值映射
QMap 存储的数据形式是一个键对应一个值,并且按照键Key的顺序存储数据。
QMap 提供了 QMap::insetMulti() h和 QMap::values() 函数,以应对一键多值的操作
存储一键多值的数据时,也可使用 QMultiMap 容器,其继承于QMap

这个 Key 表示一个关键词的意思

QHash类

QHash 具有与 QMap 几乎完全相同的API,QHash相当于维护着一张 哈希表
QHash 以任意的顺序组织它的数据。当存储数据的顺序无关紧要时,QHash就成为了最好的选择。
QHash 也可以存储 一键多值 形式的数据,它的子类 QMultiHash实现

Java 风格迭代器遍历容器
这里以 QMap 为例,QHash用法和 QMap 相似,相比之下 QHash 的查找速度会快些

 QMap<QString,QString> map; //创建一个QMap存储器对象
    //存储城市与区号
    map.insert("beijing","111");//插入一键一值的操作
    map.insert("shanghai","101");
    map.insert("chengdu","100");

    QMapIterator<QString,QString> i(map);//创建一个QMap的 只读迭代器
    for(;i.hasNext();)
    {
        i.next();
        qDebug()<<i.key()<<" : "<<i.value();//打印迭代点后的数据的项的 key 和 value

    }

    QMutableMapIterator<QString,QString> im(map); //创建一个QMap的 读写迭代器

    if(im.findNext("111")) //找到对应值得项,
    {
        im.setValue("110");
    } /*** Java 迭代器 没有提供寻找 key 的函数,所以通过寻找值来确定 ***/

    //再次遍容器
    QMapIterator<QString,QString> doc(map);//创建一个QMap的 只读迭代器
    for(;doc.hasNext();)
    {
        doc.next();
        qDebug()<<doc.key()<<" : "<<doc.value();//打印迭代点后的数据的项的 key 和 value
    }

STL 风格迭代器遍历容器

   QMap<QString,QString> map2; //创建一个QMap存储器对象
    //存储城市与区号
    map2.insert("beijing","111");//插入一键一值的操作
    map2.insert("shanghai","101");
    map2.insert("chengdu","100");

    QMap<QString,QString>::const_iterator n;//创建一个只读迭代器
    for(n=map2.constBegin();n != map2.constEnd();++n)
    {
        qDebug()<<" "<<n.key()<<":"<<n.value();
    }

    QMap<QString,QString>::iterator nm;//创建一个读写迭代器
    nm = map2.find("beijing");
    if(nm != map2.end())
    {
        nm.value()="110";
    }

    QMap<QString,QString>::const_iterator n2;//创建一个只读迭代器,输出
    for(n2=map2.constBegin();n2 != map2.constEnd();++n2)
    {
        qDebug()<<" "<<n2.key()<<":"<<n2.value();
    }

容器类3:QVariant类

QVariant类
相当于一种多变类型,它可以等于任何类型,用于存储,读取时只需要进行转化一次就行

 QVariant v(709);
    qDebug()<<v.toInt();
    QVariant v1("welcome to you!");
    qDebug()<<v1.toString();

    QMap<QString,QVariant> map;
    map["int"] = 709;
    map["double"] = 709.709;
    map["QString"] = "welcome to you!";
    map["color"] = QColor(255,0,0);

    qDebug()<<map["int"]<<" :"<<map["int"].toInt();
    qDebug()<<map["double"]<<" :"<<map["double"].toDouble();
    qDebug()<<map["QString"]<<" :"<<map["QString"].toString();
    qDebug()<<map["color"]<<" :"<<map["color"].value<QColor>();
    /***
    这样使用 value()函数进行转换是因为 QVariant 类型是属于QtCore模块的类,所以它没有QtGui模块中的数据类型(如QColor、QImage以及QPixmap等)提供转换函数,所以需要通过value()函数来操作
    ***/

    QStringList lst;
    {
        lst<<"A"<<"B"<<"C"<<"D";
    }

    QVariant v2(lst);
    if(v2.type()==QVariant::StringList)//type() 函数类确定QVariant当前所存储的数据类型
    {
        QStringList list = v2.toStringList();
        for(int i=0;i<list.size();i++)
        {
            qDebug()<<list.at(i);
        }
    }

注意:这样使用 value()函数进行转换QColor类型是因为 QVariant 类型是属于QtCore模块的类,所以它没有QtGui模块中的数据类型(如QColor、QImage以及QPixmap等)提供转换函数,所以需要通过value()函数来操作。

布局组件

vertical layout (垂直)
horizontal layout (水平)
Grid layout (网格)
Form layout (窗体)

Buttons类控件
包括:
push button、tool button、radio button、check button、command link button 、dialog button box

button

你可能感兴趣的:(Qt,qt,容器,ui)