当前位置: 首页 > article >正文

Qt修仙之路2-1 炼丹初成

在这里插入图片描述
在这里插入图片描述

widget.cpp

#include "widget.h"
#include<QDebug>
//实现槽函数
void Widget::login1()
{
    QString user=username_input->text();
    QString pass=password_input->text();
    //如果不勾选无法登入
    if(!check->isChecked()){
        qDebug()<<"xxx"<<endl;
        return;
    }
    if("123"==user&&"123"==pass){
        qDebug()<<"登入成功";
        this->close();
    }else{
        //错误清空
        password_input->setText("");
    }
}

Widget::Widget(QWidget *parent)
    : QWidget(parent)
{
    this->resize(468,657);
    //创建头像标签
    avatar=new QLabel(this);
    //移动位置
    avatar->resize(114,114);
    avatar->setStyleSheet(" border-radius: 50px;");
    avatar->move((this->width()-avatar->width())/2,95);
    //加载图片
    avatar->setPixmap(QPixmap("C:\\Users\\xzq\\Desktop\\ava.png"));
    avatar->setScaledContents(true);

    //添加输入框
    username_input=new QLineEdit(this);
    //设置大小
    username_input->resize(371,60);
    username_input->setStyleSheet(" border-radius: 10px;");
    //设置占位文本
    username_input->setPlaceholderText("请输入QQ账号");
    //设置位置
    username_input->move((this->width()-username_input->width())/2,avatar->y()+avatar->height()+30);
    //设置文本大小居中
    username_input->setFont(QFont("黑体",20,5));
    username_input->setAlignment(Qt::AlignmentFlag::AlignHCenter);

    password_input=new QLineEdit(this);
    password_input->resize(371,60);
    password_input->setStyleSheet(" border-radius: 10px;");
    password_input->move((this->width()-username_input->width())/2,avatar->y()+avatar->height()+30+80);
    password_input->setPlaceholderText("请输入QQ密码");
    password_input->setFont(QFont("黑体",10,5));
    password_input->setAlignment(Qt::AlignmentFlag::AlignHCenter);
    password_input->setEchoMode(QLineEdit::Password);

    //复选框
    check=new QCheckBox("已阅并同意",this);
    //check->resize(373,26);
    check->setStyleSheet(        "QCheckBox::indicator {"
                                 "    width: 16px;"
                                 "    height: 16px;"
                                 "    border-radius: 8px;"
                                 "    border: 1px solid gray;"
                                 "}"
                                 "QCheckBox::indicator:checked {"
                                         "    background-color: blue;"
                                         "}"
                               );
    check->move((this->width()-check->width())/2,(password_input->y()+password_input->height())+10);
    //登入按钮
    login_btn=new QPushButton("登入",this);
    login_btn->resize(371,60);
    login_btn->setStyleSheet(        "QPushButton {"
                                     "    background-color: #0099FF;"  // 正常状态背景颜色
                                     "    color: white;"  // 文字颜色
                                     "    border: none;"  // 无边框
                                     "    padding: 10px 20px;"  // 内边距
                                     "border-radius:10px;"
                                     "}"
                                     "QPushButton:pressed {"
                                     "    background-color: #97D6FF;"  // 按下状态背景颜色
                                     "}"
                             );
    login_btn->setFont(QFont("黑体",20,5));
    //移动
    login_btn->move(password_input->x(),check->y()+check->height()+20);


    //链接
    QObject::connect(login_btn,&QPushButton::clicked,this,&Widget::login1);


}

Widget::~Widget()
{
}


widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QLabel>
#include<QLineEdit>
#include<QRadioButton>
#include<QPushButton>
#include<QCheckBox>
class Widget : public QWidget
{
    Q_OBJECT
public slots:
    //登入定义槽函数
    void login1();
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private:
    QLabel *avatar;//头像
    QLineEdit *username_input;//QQ号
    QLineEdit *password_input;//密码
    QPushButton *login_btn;//登入
    QCheckBox *check;//协议

};
#endif // WIDGET_H

修仙笔记

一、对象树模型

1.1 对象树的构建

Qt中,每个QObject或其派生类对象都能有一个父对象和多个子对象。在创建对象时,如果指定了父对象,该对象会自动被添加到父对象的子对象列表中。这种父子关系形成了一种树形结构,父对象处于树的顶端,子对象在其下方,并且子对象还可以拥有自己的子对象。例如,在一个图形界面应用中,窗口可以作为父对象,而按钮、文本框等控件则是其子对象。

1.2 对象树的自动管理

这一特性是对象树模型的一大亮点。当父对象被销毁时,Qt会自动递归地销毁其所有子对象。这意味着开发者无需手动释放子对象的内存,大大简化了内存管理的过程,有效减少了内存泄漏的风险。在实际开发中,这一机制能让开发者更专注于业务逻辑的实现,而无需过多担心对象的生命周期管理。

1.3 对象树的遍历

在开发过程中,经常需要查找或遍历对象树中的子对象。Qt提供了findChildfindChildren方法,通过这两个方法,可以按名称或类型查找子对象。另外,使用children方法能够获取所有子对象的列表,方便进行遍历操作。比如,想要获取窗口中所有的按钮控件,就可以利用这些方法来实现。

1.4 对象树的事件传递

Qt的事件系统借助对象树来传递事件。事件通常从子对象向父对象传递,直到事件被处理或者到达根对象。同时,父对象还可以通过eventFilter方法拦截并处理子对象的事件。这一机制在实现一些全局的事件处理逻辑时非常有用,例如在一个包含多个输入框的窗口中,统一处理所有输入框的焦点变化事件。

1.5 对象树的动态修改

对象树支持动态修改,既可以通过setParent方法,也可以在构造函数中指定父对象来动态添加子对象。如果想要移除子对象,可以使用setParent(nullptr)将其从树中移除,但此时需要手动管理该子对象的生命周期。

二、信号与槽机制

2.1 信号

信号是类中的特殊成员函数,用于组件向外界传递信息。它定义在类体内的signals权限下,只有声明,没有函数体实现,返回值为void类型,参数可有可无。在程序需要的地方,通过emit关键字来手动发射信号。例如,一个按钮被点击时,就可以发射一个信号来通知其他组件。

2.2 槽

槽是用于接收其他组件发射的信号并执行相应逻辑的特殊成员函数,定义在类体内的slots权限下,是一个完整的函数,既有声明也有定义。槽函数不仅可以接收信号,还能当作普通成员函数被调用,但普通成员函数不能当作槽函数使用。其返回值类型通常为void,参数用于接收信号函数传递过来的数据。槽函数需要与信号函数进行连接,当信号发射时,与之连接的槽函数会自动执行。

2.3 一个包含了信号与槽的类的定义

class Widget : public QWidget
{
    Q_OBJECT          //信号与槽机制的元对象

signals:
    void my_signal();              //定义一个信号函数

public slots:
    void my_slot();               //自定义的槽函数

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private:
    Ui::Widget *ui;
};

//自定义槽函数的实现
void Widget::my_slot()
{
    // 这里编写槽函数的具体逻辑
}

2.4 信号与槽的连接

  • 基于ui界面的连接:可以直接使用系统默认提供的组件信号与槽函数进行连接。
  • 右键转到槽:在ui界面中,通过右键转到槽的方式,信号函数由系统提供,开发者可以自己实现槽函数的逻辑,此时槽函数会自动生成。
  • 手动实现QT4版本的连接:这种连接方式不太友好,需要使用SIGNAL()SLOT()两个宏函数来转换信号函数和槽函数的函数名(因为它们实际是函数指针类型,而参数要求是字符串类型)。
QObject::connect(scrollBar, SIGNAL(valueChanged(int)),
                   label,  SLOT(setNum(int)));
  • QT5版本的连接:相比QT4版本,QT5的连接方式更加简洁,直接使用信号函数和槽函数的地址进行连接。
QObject::connect(lineEdit, &QLineEdit::textChanged,
                   label,  &QLabel::setText);
  • 使用仿函数作为信号的接收者:接收信号后的处理逻辑可以是全局函数、仿函数或者Lambda表达式。

2.5 信号与槽的断开连接

如果需要断开信号与槽的连接,只需将连接函数connect改为disconnect,并根据不同的连接方式提供相应的参数即可。

    void disconnectSlots() {
        QObject::disconnect(this, &MyWidget::customSignal, this, &MyWidget::customSlot);
        qDebug() << "信号与槽已断开";
    }

http://www.kler.cn/a/536187.html

相关文章:

  • 安卓/ios脚本开发按键精灵经验小分享
  • 部署LLM模型到云端
  • MTGNN论文解读
  • 深度学习里面的而优化函数 Adam,SGD,动量法,AdaGrad 等 | PyTorch 深度学习实战
  • NacosRce到docker逃逸实战
  • 大模型实战篇之Deepseek二、一键部署DeepSeek-V3和DeepSeek-R1模型
  • JS的几种具体异常类型(报错)
  • 半导体物理与器件篇8 光电器件
  • elementui:el-table支持搜索、切换分页多选功能,以及数据回显
  • 如何使用Python的Matplotlib绘制图表?
  • 计算机毕业设计hadoop++hive微博舆情预测 微博舆情分析 微博推荐系统 微博预警系统 微博数据分析可视化大屏 微博情感分析 微博爬虫 知识图谱
  • 机器学习数学基础:15.分块矩阵
  • 函数式接口@FunctionalInterface
  • 如何优化爬虫以提高搜索效率
  • 农作物病虫害识别实操
  • DeepSeek关联WPS使用指南与案例解析
  • ADC模数转换器概念函数及应用
  • Android 实现首页Tab切换并且支持懒加载功能详解
  • 【hadoop】隐藏 hadoop/hive/spark/fink 等日志
  • 【信息系统项目管理师】第22章:组织通用治理 详解
  • 【前端】【面试】【知识点总结】react知识点大纲
  • 云轴科技ZStack+海光DCU:率先推出DeepSeek私有化部署方案
  • 【电机控制器】STC8H1K芯片——低功耗
  • ReactNative进阶(五十九):存量 react-native 项目适配 HarmonyOS NEXT
  • Java中的按值传递和引用传递
  • 【AcWing】蓝桥杯辅导课-二分与前缀和