c++ Qt5学习笔记 2021-2-22 (setContentsMargins()作用,设计布局实现的QQ消息列表,自定义控件来实现动态添加,使用数组来控制自定义控件)

44 篇文章 8 订阅

1、setContentsMargins()作用:

设置布局的边距,设置布局后,如果发现两个布局之间间距太大,可以使用setContentsMargins拉近两个布局间的距离。

setContentsMargins的四个参数分别为:左、上、右、下的边距。

使用时:

hLayout->setContentsMargins(0,20,0,0);  //左边距20,相当于该布局向右移动20px

2、QQ的消息列表:

在这里插入图片描述
其实可以使用坐标来一个一个往下搭,用坐标来搭似乎还好理解一点。想了想还是使用布局来做,坐标用多了代码就看不懂了。

大致划分如下:
在这里插入图片描述
最外面一个水平布局1水平布局1中一个头像和一个垂直布局垂直布局中是水平布局2水平布局3水平布局2中两个label水平布局3中一个label(为了方便与上面对齐,所以单独给他一个布局)。

实现的代码如下:

    //水平布局1
    //此处的message_box为stacked widget分页中的一页
    QWidget *hlayout_widget = new QWidget(ui->message_box);
    QHBoxLayout *hLayout = new QHBoxLayout(hlayout_widget);

    //竖直布局
    QWidget *vlayout_widget = new QWidget(hlayout_widget);
    QVBoxLayout *vLayout = new QVBoxLayout(vlayout_widget);

    //水平布局2
    QWidget *hlayout_widget_2 = new QWidget(vlayout_widget);
    QHBoxLayout *hLayout_2 = new QHBoxLayout(hlayout_widget_2);//水平布局2

    //水平布局3
    QWidget *hlayout_widget_3 = new QWidget(vlayout_widget);
    QHBoxLayout *hLayout_3 = new QHBoxLayout(hlayout_widget_3);//水平布局3

    //页面上的控件
    //使用qlabel作为头像时,发现setStyleSheet失效,所以改为用QPushButton
    QPushButton *Icon = new QPushButton(hlayout_widget);
    Icon->setStyleSheet("width:40px;height:40px;background-color:black;border:0px;border-radius:20px;border-image:url(:/new/prefix1/source/2.png);");
    QLabel *qq_name = new QLabel(u8"八度空间的秘密");
    QLabel *last_msg = new QLabel(u8"我肚子好饿:啊啊啊啊");
    QLabel *msg_date = new QLabel("2021-2-16");

    //向布局中添加控件
    hLayout->addWidget(Icon);
    hLayout->addWidget(vlayout_widget);
    vLayout->addWidget(hlayout_widget_2);
    hLayout_2->addWidget(qq_name);
    hLayout_2->addStretch(2);
    hLayout_2->addWidget(msg_date);
    vLayout->addWidget(hlayout_widget_3);
    hLayout_3->addWidget(last_msg);
    
    hLayout_2->setContentsMargins(0,20,0,0);
    hLayout_3->setContentsMargins(0,0,0,20);

    hlayout_widget->resize(290,110);

运行结果:
在这里插入图片描述

3、用来动态显示的自定义控件:

动态创建多个这样的消息,不可能一行一行写,所以通过自己声明控件的方式创建,之前用过,这里记录一下。

(1)布局来做:

mainwindow.h中创建public对象:

        QWidget* message_boxs(const QString &name
                              ,const QString &icon
                              ,const QString &message
                              ,const QString &msg_date) {
        //水平布局1
        QWidget *hlayout_widget = new QWidget(this);
        QHBoxLayout *hLayout = new QHBoxLayout(hlayout_widget);

        //竖直布局
        QWidget *vlayout_widget = new QWidget(hlayout_widget);
        QVBoxLayout *vLayout = new QVBoxLayout(vlayout_widget);

        //水平布局2
        QWidget *hlayout_widget_2 = new QWidget(vlayout_widget);
        QHBoxLayout *hLayout_2 = new QHBoxLayout(hlayout_widget_2);//水平布局2

        //水平布局3
        QWidget *hlayout_widget_3 = new QWidget(vlayout_widget);
        QHBoxLayout *hLayout_3 = new QHBoxLayout(hlayout_widget_3);//水平布局3

        QPushButton *qqicon = new QPushButton(this);    //头像
        QLabel *qqname = new QLabel(this);     //名字
        QLabel *qqmessage = new QLabel(this);
        QLabel *msg_date_label = new QLabel(this);

        //头像,qq名,qq信息,最后信息时间
        qqicon->setStyleSheet(QString("width:40px;height:40px;border:0px;border-radius:20px;border-image:url(:/new/prefix1/source/%1);").arg(icon));
        qqname->setText(name);
        qqmessage->setText(message);
        msg_date_label->setText(msg_date);

        hLayout->addWidget(qqicon);
        hLayout->addWidget(vlayout_widget);
        vLayout->addWidget(hlayout_widget_2);
        vLayout->addWidget(hlayout_widget_3);
        hLayout_2->addWidget(qqname);
        hLayout_2->addStretch(2);
        hLayout_2->addWidget(qqmessage);
        hLayout_3->addWidget(msg_date_label);

        hLayout_2->setContentsMargins(0,20,0,0);
        hLayout_3->setContentsMargins(0,0,0,20);

        hlayout_widget->resize(290,125);

        return hlayout_widget;
    }

mainwindow.cpp中添加:

    //此处的message_box为stacked widget分页中的一页
    QWidget *vlayout_main_widget = new QWidget(ui->message_box);
    QVBoxLayout *vLayout_main = new QVBoxLayout(vlayout_main_widget);
    
    //这里可以使用数据库中查询到的数据批量添加
    QWidget *message_box1 = message_boxs(u8"懒羊羊","2.png",u8"我肚子好饿:啊啊啊啊","20:21");
    QWidget *message_box2 = message_boxs(u8"慢羊羊","3.png",u8"我肚子好饿:啊啊啊啊","20:21");
    QWidget *message_box3 = message_boxs(u8"喜羊羊","2.png",u8"我肚子好饿:啊啊啊啊","20:21");
    vLayout_main->addWidget(message_box1);
    vLayout_main->addWidget(message_box2);
    vLayout_main->addWidget(message_box3);

运行结果:
在这里插入图片描述
基本就有个雏形了,还要调节一下上下间距,再加个滚动条。图简单的话,接下来可以不使用布局来做了,可以把自己自建的控件是用坐标一个一个往下排就行了。

(2)坐标来做:

mainwindow.h中创建public对象:

    QWidget* message_boxs(const QString &name
                          ,const QString &icon
                          ,const QString &message
                          ,const QString &msg_date) {
        QWidget *qwidget = new QWidget(this);

        QPushButton *qqicon = new QPushButton(qwidget);    //头像
        QLabel *qqname = new QLabel(qwidget);     //名字
        QLabel *qqmessage = new QLabel(qwidget);
        QLabel *msg_date_label = new QLabel(qwidget);

        //头像,qq名,qq信息,最后信息时间
        qqicon->setStyleSheet(QString("width:40px;height:40px;border:0px;border-radius:20px;border-image:url(:/new/prefix1/source/%1);").arg(icon));
        qqname->setText(name);

        qqmessage->setText(message);
        qqmessage->setStyleSheet("color:rgb(173,173,173)");
        msg_date_label->setText(msg_date);

        qqicon->move(15,10);
        qqname->move(65,15);
        qqmessage->move(65,35);
        msg_date_label->move(240,15);

        qwidget->resize(290,60);
        return qwidget;
    }

mianwindow.cpp中放置控件:

    QWidget *message_box1 = message_boxs(u8"懒羊羊","2.png",u8"我肚子好饿:啊啊啊啊","20:21");
    QWidget *message_box2 = message_boxs(u8"慢羊羊","3.png",u8"我肚子好饿:啊啊啊啊","20:21");
    QWidget *message_box3 = message_boxs(u8"喜羊羊","2.png",u8"我肚子好饿:啊啊啊啊","20:21");

    message_box1->setParent(ui->message_box);
    message_box1->move(0,0);
    message_box1->setStyleSheet("background-color:rgb(127,127,127)"); //为了定制高度,所以用颜色标识出来,可不用
    message_box2->setParent(ui->message_box);
    message_box2->move(0,60);
    message_box3->setParent(ui->message_box);
    message_box3->move(0,120);

运行结果:
在这里插入图片描述
之前尝试过自建设计师界面类,画一个界面,然后作为控件来放置。虽然能放,但是不会随着一起放缩和移动,所以放弃了。

(3)使用容器数组来控制:

这里紧接着上面坐标实现的操作。

mainwindow.h中创建public对象:

QList<QWidget *> qWidget_group;

mainwindow.cpp中创建自建控件:

    QStringList namelist,iconlist,meslist,timelist;
    //使用时,以下内容就可以替换为数据库中的信息。
    //像QQ中那样则应该还需要把信息传递给服务器,信息等存储在本地,
    //朋友的头像和其他信息等需要在服务器下载
    namelist.append(u8"喜羊羊");
    namelist.append(u8"懒羊羊");
    namelist.append(u8"慢羊羊");
    namelist.append(u8"泰哥");
    iconlist.append("1.jpg");
    iconlist.append("4.jpg");
    iconlist.append("5.jpg");
    iconlist.append("15.jpg");
    meslist.append(u8"哈哈哈哈");
    meslist.append(u8"我肚子好饿");
    meslist.append(u8"发生肾莫事了");
    meslist.append(u8"我一拳头下去就把他鼻子打骨折了");
    timelist.append("20:21");
    timelist.append("20:21");
    timelist.append("20:21");
    timelist.append("20:21");
    
    for(int i=0;i<4;i++)
        qWidget_group.push_back(message_boxs(namelist.at(i)
                                             ,iconlist.at(i)
                                             ,meslist.at(i)
                                             ,timelist.at(i))),
        qWidget_group[i]->setParent(ui->message_box),
        //鼠标悬浮效果
        qWidget_group[i]->setStyleSheet("QWidget::hover{background-color:rgb(235,235,235)}"),
        qWidget_group[i]->move(0,60*i);

运行结果:
在这里插入图片描述

在这里插入图片描述

迷你仪表盘是一种自定义控件,主要用于显示简单的数据指示或状态显示。在Qt/C++中编写自定义迷你仪表盘需要以下步骤: 1. 创建一个新的自定义控件类,可以继承QWidget或QLabel。在类的构造函数中初始化一些基本属性,例如仪表盘的大小、颜色、范围等。 2. 重写paintEvent函数,该函数用于绘制仪表盘的外观。在paintEvent函数中,可以使用QPainter绘制各种图形元素,例如圆形、刻度线、指针等。可以根据数据范围和当前值来动态改变指针的位置或角度。 3. 定义一些公有的函数或信号槽,用于设置或更新仪表盘的值。例如,可以定义一个setValue函数用于设置当前值,并在函数内部调用update函数来触发重绘事件。 4. 在主窗口或其他需要使用仪表盘的地方,实例化自定义的迷你仪表盘控件,并设置一些属性,例如位置、大小、初始值等。还可以通过设置样式表来对仪表盘进行外观的自定义。 5. 根据需要,可以添加一些交互功能。例如,可以响应鼠标点击事件,以实现互动操作,例如点击指针可以通过setValue函数来设置对应的值。 编写自定义控件需要一定的Qt/C++编程基础和绘图知识,掌握了基本的绘图函数和事件处理机制后,可以根据需求进行扩展和优化。同时,为了提高代码的可重用性和可维护性,可以将控件的逻辑和外观分离,采用MVC设计模式或其他架构模式进行开发。
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值