stigmt
@stigmt
Учусь

Как пользоваться QDataStream?

Вопросы знатокам.
1: (это метод добавления одной строки в конец другой, верно?) append() используется таким вот образом:

QString str = "rock and";

    str.append(" roll");            // str == "rock and roll"

В моем же примере из учебника вот так append("Sent:" + dt.toString()); и не ясно что к чему в этом участке кода

2: Мне не понятно что и как выводит оператор outТ.к если убрать <<dtи вообще исключить из кода, оставив просто out;
то на выходе будет просто "Sent:". Если я объявляю Qstring str = "123" и пишу out << str , вывод не меняется

3: как сделать что бы работало что-то типа такого?
out<<str;
Полный код:
void UdpServer::slotSendDatagram()
{
    QByteArray baDatagram;
    QDataStream out(&baDatagram, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_3);
    QDateTime dt = QDateTime::currentDateTime();
    append("Sent:" + dt.toString());
    out << dt;
    m_pudp->writeDatagram(baDatagram, QHostAddress::LocalHost, 2424);
}


.cpp
#include <QtNetwork>
#include <QtGui>
#include "UdpServer.h"

// ----------------------------------------------------------------------
UdpServer::UdpServer(QWidget* pwgt /*=0*/) : QTextEdit(pwgt)
{
    setWindowTitle("UdpServer");

    m_pudp = new QUdpSocket(this);

    QTimer* ptimer = new QTimer(this);
    ptimer->setInterval(500);
    ptimer->start();
    connect(ptimer, SIGNAL(timeout()), SLOT(slotSendDatagram()));
}

// ----------------------------------------------------------------------
void UdpServer::slotSendDatagram()
{
    QByteArray baDatagram;
    QDataStream out(&baDatagram, QIODevice::WriteOnly);
    out.setVersion(QDataStream::Qt_5_3);
    QDateTime dt = QDateTime::currentDateTime();
    append("Sent:" + dt.toString());
    out << dt;
    m_pudp->writeDatagram(baDatagram, QHostAddress::LocalHost, 2424);
}

.h
#pragma once

#include <QTextEdit>

class QUdpSocket;

// ======================================================================
class UdpServer : public QTextEdit {
Q_OBJECT
private:
    QUdpSocket* m_pudp;

public:
    UdpServer(QWidget* pwgt = 0);

private slots:
    void slotSendDatagram();
};
  • Вопрос задан
  • 1910 просмотров
Решения вопроса 1
@abcd0x00

1: (это метод добавления одной строки в конец другой, верно?) append() используется таким вот образом:

В моем же примере из учебника вот так append("Sent:" + dt.toString()); и не ясно что к чему в этом участке кода

Это разные методы. В твоём примере используется метод append() у QTextEdit, так как от этого класса наследуется твой UdpServer.


2: Мне не понятно что и как выводит оператор outТ.к если убрать <<dt и вообще исключить из кода, оставив просто out;
то на выходе будет просто "Sent:". Если я объявляю Qstring str = "123" и пишу out << str , вывод не меняется

out - это не оператор, а переменная типа QDataStream. У класса QDataStream переопределена (говорят перегружена, но это неправильно) операция побитового сдвига влево.

Ты бы изучил сначала основы C++, потому что вопросы у тебя именно по ним, а не по Qt. Надо сначала изучить C++, а потом Qt, а не наоборот.

Ты когда делаешь
out << x
переменная x пишется в out, потому что у out запускается метод <<, в который передаётся значение x. И этот метод понимает, как это значение сохранить, и знает, куда его там сохранить.

QDataStream - это сериализатор, он принимает любые объекты и приводит их к определённому виду, чтобы потом на любой другой системе из этого определённого вида можно было эти объекты обратно прочитать и получить те же самые данные тех же самых типов.

Почему у тебя что-то куда-то не пишется? Потому что ты не понимаешь, что ты делаешь. Зачем, например, ты наследуешь сервер от текстового окна? Если тебе нужен вывод сервера, сервер должен его передавать в отдельное окно, используя сигнальную систему.
Ответ написан
Пригласить эксперта
Ответы на вопрос 1
@koronabora
Человек
Вот кусок из рабочего проекта, способ использования взят из документации qt.

void TcpClient::sendToServer(QString data)
{
	if (_socket != Q_NULLPTR)
	{
		res = "";

		while (_socket->state() != QAbstractSocket::ConnectedState)
		{
			if (_socket->state() != QAbstractSocket::ConnectingState && _socket->state() != QAbstractSocket::HostLookupState)
			{
				_socket->connectToHost(_name, _port); // try to connect
				alreadyConnected = true;
			}
			QApplication::processEvents();
			QThread::currentThread()->msleep(NET_IO_CONNECT_DELAY);
			qDebug() << "waiting for connection";
		}

		if (alreadyConnected) // we connected to server few times ago. Let's wait
		{
			QThread::currentThread()->msleep(NET_IO_DELAY_AFTER_CONNECTION);
			alreadyConnected = false;
		}
		qDebug() << "Send to server";
		QByteArray block; 
		QDataStream out(&block, QIODevice::WriteOnly); 
		out.setVersion(QDataStream::Qt_5_6);
		out << (quint16)0; // Забиваем память под размер
		out << _realId; // записываем реальные данные
		out << data; // еще немного реальных данных
		out.device()->seek(0); // переходим на начало
		out << (quint16)(block.size() - sizeof(quint16) - sizeof(quint64)); // записываем размер сообщения
		quint64 sss = _socket->write(block); // отправляем в сокет
		if (sss < block.size()) // сокет сожрал не все
			qDebug() << "Буфер маловат будет!" << sss << " != " << block.size(); //
		else if (sss > block.size()) // сокет сожрал больше, чем необходимо
			qDebug() << "Что-то лишнее в буфере! " << sss << " != " << block.size(); //
		qDebug() << "Data written: " << data; // сокет все-таки молодец
		_socket->flush(); // выталкиваем данные в сеть
		_lastMessage = data;
		_timeOutTimer->setSingleShot(true); // ждем немного
		_timeOutTimer->start(NET_IO_DELAY); // чтобы сетевой стек успел отправить данные
	}
	else qDebug() << "Socket is null!";
}
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы