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

news/2025/2/8 11:53:09 标签: qt, 开发语言

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

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.niftyadmin.cn/n/5844832.html

相关文章

为多个GitHub账户配置SSH密钥

背景 当需要同时使用多个GitHub账户&#xff08;例如工作和个人账户&#xff09;时&#xff0c;默认的SSH配置可能导致冲突。本文介绍如何通过生成不同的SSH密钥对并配置SSH客户端来管理多个账户。 操作步骤 生成SSH密钥对 为每个GitHub账户生成独立的密钥对&#xff0c;并指…

数据结构与算法面经

排序算法 冒泡排序:通过相邻元素的比较和交换,每次将最大(或最小)的元素逐步“冒泡”到最后(或最前)。时间复杂度:最好情况下O(n),最坏情况下O(n2),平均情况下O(n2)。,空间复杂度:O(1)。插入排序:将待排序元素逐个插入到已排序序列的合适位置,形成有序序列。时间复…

tomcat如何配置保存7天滚动日志

在 Tomcat 中&#xff0c;logging.properties 文件是用于配置 Java 日志框架&#xff08;java.util.logging&#xff09;的。若要实现 catalina.out 日志保存 7 天&#xff0c;且每天的日志文件名带有时间戳&#xff0c;可以按以下步骤进行配置&#xff1a; 1. 备份原配置 在修…

本文主要详细讲解ArcGIS中的线、多线段和多边形的结构关系。

在ArcGIS的定义中&#xff0c;线部分的类结构视图如下&#xff1a; 从上图可以非常直观地看到其结构关系。 一、线段&#xff08;ISegment&#xff09; ArcGIS中的线段都继承于ISegment&#xff0c;分四种线段。贝拉曲线&#xff08;IBezierCurve&#xff09;、直线段&…

【Android】版本和API对应关系表

目录 版本和API对应关系表 不积跬步&#xff0c;无以至千里&#xff1b;不积小流&#xff0c;无以成江海。要沉下心来&#xff0c;诗和远方的路费真的很贵&#xff01; 版本和API对应关系表 版本名版本号名称APIAndroid 1616.0W36Android 1515.0V35Android 1414.0U34Android 1…

vue项目如何设置默认页面

j​​​​​​​​​​​​​​​​​​​​​​​​​​​​创建一个新的vue项目并且将初始页面还原到空白项目开始 - 现实里的乌托邦 - 博客园 vue项目如何设置默认页面 • Worktile社区 创建一个vue项目并配置默认页面_vue如何设置初始展示的页面-CSDN博客 新建的vue项目…

Android13-系统服务大管家-ServiceManager进程-启动篇

文章目录 关注 ServiceMager 原因ServerManager需要掌握的知识资料参考ServiceManager 进程启动启动脚本涉及到的相关源码文件源码跟踪ServiceManager脚本启动位置ServiceManager关联脚本 Native层源码分析main.cpp流程打开驱动 initWithDriverinitmakeProcessState 构造方法op…

CentOS 7配置samba服务设置文件共享

CentOS 7配置samba服务设置文件共享 一、生成另一个Linux系统&#xff0c;名为Linux-client&#xff0c;作为测试系统。 [rootliunx-client ~]# hostnamectl set-hostname Liunx-client二、如果没有则安装Samba服务&#xff0c;如果已经安装则省略此步。 yum install samba…