0
点赞
收藏
分享

微信扫一扫

riscv-gnu-toolchain 交叉编译器如何构建?

ZSACH 04-14 09:30 阅读 2

一、对象模型(对象树)

  • 1、Qt引入对象树的概念,在一定程度上解决了内存问题;
  • 2、当一个Q0bject对象在堆上创建的时候,Qt会同时为其创建一个对象树;
  • 3、不过,对象树中对象的顺序是没有定义的;
  • 4、这意味着,销毁这些对象的顺序也是未定义的;
在Qt中创建对象的时候会提供一个Parent对象指针,

下面来解释这个parent到底是干什么的。
------------------------------------------------

Q0bject是以对象树的形式组织起来的。
--------------------------------------------

当你创建一个Q0bject对象时,会看到Q0bject的构造函数接收一个

QObject指针作为参数,这个参数就是parent, 也就是父对象指针。
-------------------------------------------------------------------------------


----------------------------------------------------------------------
这相当于,在创建Q0bject对象时,可以提供一个其父对象,我们创建

的这个Q0bject对象会自动添加到其父对象的children()列表。


------------------------------------------------------------------------------
当父对象析构的时候,这个列表中的所有对象也会被析构。

(注意,这里的父对象并不是继承意义上的父类!)
---------------------------------------------------
这种机制在GUI程序设计中相当有用。
---------------------------------------------------------
例如,一个按钮有一个QShortcut (快捷键)对象作为其子对象。

当我们删除按钮的时候,这个快捷键理应被删除。

这是合理的。

--------------------------------------------------------------
QWidget 是能够在屏幕上显示的一切组件的父类。
----------------------------------------------------------------


QWidget继承自QObject,因此也继承了这种对象树关系。

一个孩子自动地成为父组件的一个子组件。
------------------------------------------------------------

因此,它会显示在父组件的坐标系统中,被父组件的边界剪裁。

例如,当用户关闭一个对话框的时候,应用程序将其删除,

那么,我们希望属于这个对话框的按钮、图标等应该一起被删除。

事实就是如此,因为这些都是对话框的子组件。
--------------------------------------------------------------

当然,我们也可以自己删除子对象,它们会自动从其父对象列表中删除。
---------------------------------------------------------------------------------

比如,当我们删除了一个工具栏时,

其所在的主窗口会自动将该工具栏从其子对象列表中删除,

并且自动调整屏幕显示。

任何对象树中的Q0bject 对象delete 的时候,

如果这个对象有parent,则自动将其从parent 的children()列表中删除;

如果有孩子,则自动delete每一个孩子。

Qt保证没有Q0bject会被delete 两次,这是由析构顺序决定的。

二、TCP服务器

server.pro
------------------
QT       += core gui network
----------------------------
widget.h
------------------
#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void on_startBtn_clicked();
    void on_senderBtn_clicked();
private:
    Ui::Widget *ui;
    QTcpServer* server;
    QTcpSocket* socket;
};
#endif // WIDGET_H


--------------------------------
widget.cpp
---------------------
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("服务器");
    //在堆上定义对象:sever对象,通信套接字对象
    this->server = new QTcpServer(this);
    this->socket = new QTcpSocket(this);
    //使用信号与槽的方式建立关联关系:
    connect(this->server,&QTcpServer::newConnection,[=](){
        //获得了新的链接套接字对象的起始地址。
        this->socket = this->server->nextPendingConnection();
        ui->chatlogText->append("新的客户机连接了服务器");
        //对这一个连接套接字对象建立关联关系:
        connect(this->socket,&QTcpSocket::readyRead,[=](){
            QString recvMsg = this->socket->readAll();
            ui->chatlogText->append("客户机发来的数据:" + recvMsg);
        });
        connect(this->socket,&QTcpSocket::disconnected,[=](){
            //this->socket->close();
            this->socket->deleteLater();//安全的释放套接字资源的方式。
        });
    });
}
Widget::~Widget()
{
    delete ui;
}

void Widget::on_startBtn_clicked()
{
    quint16 port = ui->port_line->text().toUShort();
    this->server->listen(QHostAddress::Any,port);
    ui->startBtn->setEnabled(false);
}
void Widget::on_senderBtn_clicked()
{
    QString senderMsg = ui->senderText->toPlainText();
    this->socket->write(senderMsg.toUtf8());
    ui->senderText->clear();
}

三、TCP客户端

client.pro
--------------------
QT       += core gui network
------------------------------------



widget.h
----------------------
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_connectBtn_clicked();
    void on_disconnectBtn_clicked();
    void on_senderBtn_clicked();
private:
    Ui::Widget *ui;
    QTcpSocket* socket;
};
#endif // WIDGET_H


------------------------

widget.cpp
---------------
#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("客户端");
    this->socket = new QTcpSocket(this);


    //使用信号与槽绑定关联关系:
    connect(this->socket,&QTcpSocket::connected,[=](){
        ui->chatTextRoom->append("已经连接上服务器");
    });


    //有数据可读时:
    connect(this->socket,&QTcpSocket::readyRead,[=](){
        QString recvMsg = this->socket->readAll();
        ui->chatTextRoom->append(recvMsg);
    });


    //对端断开连接:
    connect(this->socket,&QTcpSocket::disconnected,[=](){
        this->socket->close();
    });
}


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




void Widget::on_connectBtn_clicked()
{
    QString serverIP = ui->ip_line->text();
    quint16 serverPort = ui->port_line->text().toUShort();
    this->socket->connectToHost(serverIP,serverPort);
    ui->connectBtn->setEnabled(false);
}


void Widget::on_disconnectBtn_clicked()
{
    this->socket->close();
}


void Widget::on_senderBtn_clicked()
{
    QString senderMsg = ui->userName_line->text() + ": " + ui->senderMsgText->toPlainText();
    this->socket->write(senderMsg.toUtf8());
    ui->senderMsgText->clear();
}

四、TCP并发服务器

  • QTcpserver并发服务器设计思路:
------------------------------------
mytcpserver.h:
----------------
#ifndef MYTCPSERVER_H
#define MYTCPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>

class MyTcpServer : public QTcpServer
{
    Q_OBJECT
public:
    explicit MyTcpServer(QObject *parent = nullptr);
    QList<QTcpSocket*> getSocketList();
protected:
    //重写incomingConnection
    void incomingConnection(qintptr handle) override;
signals:
    void mytcpserver_signals(const QString& recvMsg);


private:
    QList<QTcpSocket*> socket_list;


};


#endif // MYTCPSERVER_H




----------------------------

mytcpserver.cpp:
------------------------
#include "mytcpserver.h"
MyTcpServer::MyTcpServer(QObject *parent) : QTcpServer(parent)
{
}
QList<QTcpSocket *> MyTcpServer::getSocketList()
{
    return this->socket_list;
}
void MyTcpServer::incomingConnection(qintptr handle)
{
    //定义一个套接字对象:
    QTcpSocket* socket = new QTcpSocket(this);
    //把套接字对象设置为链接套接字对象:
    socket->setSocketDescriptor(handle);
    //添加到容器中:
    this->socket_list.append(socket);
    //有数据可读时的逻辑的处理:
    connect(socket,&QTcpSocket::readyRead,[=](){
        QString recvMsg = socket->readAll();
        emit this->mytcpserver_signals(recvMsg);
        //对所有在容器的链接套接对象进行广播:
        for(QTcpSocket* mysocket : this->socket_list)
        {
            mysocket->write(recvMsg.toUtf8());
        }
    });
    //关闭时的逻辑处理
    connect(socket,&QTcpSocket::disconnected,[=](){
        socket->close();
        this->socket_list.removeOne(socket);
    });
}

--------------------------------------------




widget.h:
--------------
#ifndef WIDGET_H
#define WIDGET_H


#include <QWidget>
#include <QTcpSocket>
#include "mytcpserver.h"
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE
class Widget : public QWidget
{
    Q_OBJECT
public:
    Widget(QWidget *parent = nullptr);
    ~Widget();
private slots:
    void on_startBtn_clicked();
    void on_senderBtn_clicked();
private:
    Ui::Widget *ui;
    MyTcpServer* server;
};
#endif // WIDGET_H



--------------------------

widget.cpp:
-----------------


#include "widget.h"
#include "ui_widget.h"
Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    this->setWindowTitle("服务器");
    //在堆上定义对象:sever对象,通信套接字对象
    this->server = new MyTcpServer(this);
    //信号与槽绑定自定义并发服务器发来的信号,在槽中接收到读取后的信号:
    connect(this->server,&MyTcpServer::mytcpserver_signals,[=](const QString& recvMsg){
        ui->chatlogText->append(recvMsg);
    });
}
Widget::~Widget()
{
    delete ui;
}

void Widget::on_startBtn_clicked()
{
    quint16 port = ui->port_line->text().toUShort();
    this->server->listen(QHostAddress::Any,port);
    ui->startBtn->setEnabled(false);
}
void Widget::on_senderBtn_clicked()
{
    QString senderMsg = ui->senderText->toPlainText();
    for(QTcpSocket* mysocket : this->server->getSocketList())
    {
        mysocket->write(senderMsg.toUtf8());
    }
    ui->senderText->clear();
}

举报

相关推荐

0 条评论