Qt WebSockets, how to send a message to client - c++

I'm following this example http://doc.qt.io/qt-5/qtwebsockets-echoserver-example.html but I can't figure out how to send a message to client after the connection has been made.
This seems to work but only when it's inside a function from another class.
void EchoServer::processTextMessage(QString message)
{
m_clients.at(0)->sendTextMessage("test");
}
Where / How should I put the code to get it working?
e. g. How to send a message to client after a button has been pressed in MainWindow?
This is working
void EchoServer::processTextMessage(QString message)
{
m_clients.at(0)->sendTextMessage("test");
}
This isn't working
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
m_clients.at(0)->sendTextMessage("test");
}
Neither this
void MainWindow::myclicked()
{
m_clients.at(0)->sendTextMessage("test");
}

I got it working. Here is the code:
QWebSocket *messageSocket;
void EchoServer::onNewConnection()
{
QWebSocket *pSocket = m_pWebSocketServer->nextPendingConnection();
connect(pSocket, &QWebSocket::textMessageReceived, this, &EchoServer::processTextMessage);
connect(pSocket, &QWebSocket::disconnected, this, &EchoServer::socketDisconnected);
m_clients << pSocket;
messageSocket=pSocket;
}
void MainWindow::myclicked()
{
if (messageSocket)
{
messageSocket->sendTextMessage("test");
}
}

Related

QT UDP socket does not recive any thing

I have a STM32 and it would send and receive UDP packets successfully with hercules_3-2-8.
Now I have this simple code in QT, it can send UPD packets, But it would not receive any thing, the readyRead slot would never be called,
MyUDP::MyUDP(QObject *parent) : QObject(parent)
{
socket = new QUdpSocket(this);
socket->bind(QHostAddress("192.168.1.100"),2000);
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()));
}
void MyUDP::SayHello(){
QByteArray Data;
Data.append("Hello from ASiDesigner");
socket->writeDatagram(Data,QHostAddress("192.168.1.100"),2000);
qDebug()<<"Hi Nitrogen";
}
void MyUDP::readyRead(){
QByteArray Buffer;
Buffer.resize((socket->pendingDatagramSize()));
QHostAddress sender;
quint16 senderPort;
socket->readDatagram(Buffer.data(),Buffer.size(),&sender,&senderPort);
qDebug()<<"Message from: "<<sender.toString();
qDebug()<<"Message port: "<<senderPort;
qDebug()<<"Message: "<<Buffer;
}
The mainwindow.cpp file content
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myudp.h"
MyUDP Server;
MyUDP client;
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
client.SayHello();
}
The problem was solved by moving all the related UDP functions into the mainwindow.cpp file, Maybe it's related to priories in QT!

Creating a progress bar for audio playback in Qt Widgets

I'm currently working on a Qt Widget (using Qt 6.3) that plays audio and shows a progressbar. But I'm struggling to find a way to connect the audio progress value with the progress bar status.
Here's my code:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
mMediaPlayer = new QMediaPlayer(this);
audio_output = new QAudioOutput(this);
//this is the part I need help with
connect(mMediaPlayer, SIGNAL(positionChanged(qint64)), this, SLOT(positionChanged(qint64)));
void MainWindow::on_Button_open_media_clicked()
{
QString file_name = QFileDialog::getOpenFileName(this, "Open");
if(file_name.isEmpty()){
return;
}
mMediaPlayer->setSource(QUrl::fromLocalFile(file_name));
mMediaPlayer->setAudioOutput(audio_output);
audio_output->setVolume(ui->volume_slider->value());
on_play_button_clicked();
}
void MainWindow::on_stop_button_clicked()
{
mMediaPlayer->stop();
}
void MainWindow::on_pause_button_clicked()
{
mMediaPlayer->pause();
}
void MainWindow::on_play_button_clicked()
{
audio_output->setVolume(100);
mMediaPlayer->play();
}
void MainWindow::on_mute_button_clicked()
{
if(ui->mute_button->text() == "Mute"){
audio_output->setMuted(true);
ui->mute_button->setText("Unmute");
}
else{
audio_output->setMuted(false);
ui->mute_button->setText("Mute");
}
}
void MainWindow::on_volume_slider_valueChanged(int value)
{
audio_output->setVolume(value);
}
}
I couldn't find a way to do it using the documentation. It might be simple, but I need help.
Any help is gladly appreciated.

How to Connect Signal from MainWindow to Slot in Dialog

I have signal in my MainWindow to emit a number thats in a line edit. When I click a button to open the dialog, I want that number to be copied to the line edit in the dialog. I can't get it to connect. I can see the signal is emitting with qDebug. Am I connecting it wrong or in the wrong place? I have tried many ways. Here are my code snippets.
Mainwindow
//My MainWindow
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent), ui(new Ui::MainWindow) {
ui->setupUi(this);
//This is the number I am trying to send to the dialog
ui->checkingAmount->setText(QString::number(1000.00, 'f', 2));
ui->checkingAmount->setReadOnly(true);
}
//Emit the data here
void MainWindow::on_transferButton_clicked() {
transferWindow = new TransferWindow(this);
transferWindow->show();
//trying to emit the data
QString data =ui->checkingAmount->text();
emit shareCheckingData(data);
qDebug()<<"emitting mainwin amount";
}
Dialog
//My Dialog
TransferWindow::TransferWindow(QWidget *parent) : QDialog(parent),ui(new Ui::TransferWindow) {
ui->setupUi(this);
//I have tried several variations of this
//mainWindow = new MainWindow();
connect(mainWindow, SIGNAL(shareCheckingData(QString)),this, SLOT(getAmountFromMainWin(QString)));
}
//Here is the connecting slot to get the data from main window
void TransferWindow::getAmountFromMainWin(QString n) {
float CheckTotal = n.toFloat();
ui->checkingAmount->setReadOnly(true);
ui->checkingAmount->setText(QString::number(CheckTotal));
qDebug()<<"setting amount";
}
How can I get this to connect? I read through many posts and it did not solve the problem. Thanks.
I notice in the comments of your code that you intend to create an instance of MainWindow and try to connect to this instance, that is a new instance different from the previous one so you will not be able to get it.
First we must create the instance and then connect it, that we can do in the constructor.
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->checkingAmount->setText(QString::number(1000.00, 'f', 2));
ui->checkingAmount->setReadOnly(true);
transferWindow = new TransferWindow(this);
connect(this, &MainWindow::shareCheckingData, transferWindow, &TransferWindow::getAmountFromMainWin);
//old style
//connect(this, SIGNAL(shareCheckingData(QString)), transferWindow, SLOT(getAmountFromMainWin(QString)));
}
void MainWindow::on_transferButton_clicked()
{
//trying to emit the data
QString data =ui->checkingAmount->text();
emit shareCheckingData(data);
qDebug()<<"emitting mainwin amount";
transferWindow->show();
}
TransferWindow.cpp
TransferWindow::TransferWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::TransferWindow)
{
ui->setupUi(this);
}
void TransferWindow::getAmountFromMainWin(QString n)
{
float CheckTotal = n.toFloat();
ui->checkingAmount->setReadOnly(true);
ui->checkingAmount->setText(QString::number(CheckTotal));
qDebug()<<"setting amount";
}

Qt c++ double emit Data

I have a multiserverapp that works fine so far. I got 4 cpp files.
Main.cpp constructs the program. MainWindow.cpp constructs the ui and starts (via buttonclick) MyServer.cpp. MyServer.cpp creates a thread and starts MyThread.cpp.
My aim is to show several major steps (like the "server started", "new connection", etc..) on a textBrowser.
I pass the outputs from MyServer.cpp via emit updateUI("server started"); to mainwindow.cpp where the output gets catched by:
//Mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "myserver.h"
#include "mythread.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::AppendToBrowser(const QString text)
{
ui->textBrowser->append(text);
}
void MainWindow::on_startButton_clicked()
{
MyServer* mServer = new MyServer;
connect(mServer, SIGNAL(updateUI(const QString)), this, SLOT(AppendToBrowser(const QString)));
mServer->StartServer();
ui->textBrowser->setPlainText("Server Started");
}
That works just right because the connect command is just in the mainwindow.cpp itself.
The problem starts one step "deeper" in the mythread.cpp.
I created another signal in the
//MyThread.h
signals:
void updateUI_serv(const QString text);
and connected it in the MyServer.cpp with the MainWindow.cpp.
//MyServer.cpp
#include "myserver.h"
#include "mainwindow.h"
MyServer::MyServer(QObject *parent) :
QTcpServer(parent)
{
}
void MyServer::StartServer()
{
if(!this->listen(QHostAddress::Any,1234))
{
qDebug("Server Error");
}
else
{
qDebug("Server started");
}
}
void MyServer::incomingConnection(int socketDescriptor)
{
qDebug("new connection");
MyThread *thread = new MyThread(socketDescriptor,this);
MainWindow *mMain = new MainWindow;
connect(thread, SIGNAL(updateUI_serv(const QString)),mMain ,SLOT(AppendToBrowser(const QString)));
//flags thread for selfdeletion
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));
//calls run
thread->start();
emit updateUI("thread started!");
}
// MyThread.cpp
#include "mythread.h"
#include "mainwindow.h"
#include "myserver.h"
MyThread::MyThread(int ID, QObject *parent) :
QThread(parent)
{
this->socketDescriptor = ID;
emit updateUI_serv("start");
}
void MyThread::run()
{
//thread stars here
qDebug("Starting thread");
socket = new QTcpSocket();
emit updateUI_serv("hallo");
//set socketdescriptor number
if(!socket->setSocketDescriptor(this->socketDescriptor))
{
emit error(socket->error());
return;
}
connect(socket, SIGNAL(readyRead()), this, SLOT(readyRead()), Qt::DirectConnection);
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected()), Qt::DirectConnection);
qDebug("client connected");
exec();
}
void MyThread::readyRead()
{
QByteArray Data = socket->readAll();
QString Datain = QString::fromLatin1(Data);
qDebug("Date in:");
emit updateUI_serv("data in:");
socket->write(Data);
}
void MyThread::disconnected()
{
qDebug("Disconnected");
socket->deleteLater();
exit(0);
}
The connect command lays here "in between" the signal (updateUI_serv from mythread.cpp) and the slot (AppendToBrowser from mainwindow.cpp) file.
At this point the program crashes as soon as I try to write data (as a client via telnet) to the serverapp.
I tried to set the connect command into the mainwindow and the mythread as well, but both times I get different problems (like debugging problems, or the text does just not show up in the textBrowser).
Thanks so far.
Eventually the myServer-Object is not running in the MainThread, therefor accessing an ui element from another thread crashes your app.
You can make sure only Messages from mainThread will get displayed by adding the following code to your AppendToBrowser Slot:
if( QApplication::instance()->thread() == QThread::currentThread() )
ui->textBrowser->setPlainText("whateverTextThereShallBe");
else
return;
//You should not run into this else...
This if section checks if the current object calling the update is the mainThread. The else-section checks for erros. If you are running in the else-section you are trying to change ui-elements form a thread which is not the mainThread (UI-Thread). Connect your SIGNAL in server to another SIGNAL (SIGNAL->SIGNAL connection) and add a connect to SIGNAL(SERVER) -> SLOT(MainWindow) in your MainWindow.cpp. Eventually try your connect-call with the 5th. parameter for Queued Connection (Qt::QueuedConnection IIRC).
Ahh i got it on my own.
I solved the problem by creating a NEW function ( void forwarding(const Qstring); ) and in that function i emitted it with the ordinary emit updateUI(text); .. stuff works finaly!

Trying to connect QTcpServer to GUI with signals

I created a connection between server and client, the connection works fine in console, but i coudn't connect my QTcpServer class to GUI with signals and slots. Here is my code :
ServerTCP.cpp
ServerTcp :: ServerTcp (QWidget *parent)
{
listen(QHostAddress::Any,4000);
QObject:: connect(this, SIGNAL(newConnection()),
this, SLOT(connectionRequest()));
}
void ServerTcp :: connectionRequest()
{
emit IHM_connection();
clientConnection = nextPendingConnection();
QObject:: connect(clientConnection, SIGNAL(readyRead()),
this, SLOT(read()));
}
void ServerTcp::read()
{
QString ligne;
while(clientConnection->canReadLine())
{
ligne = clientConnection->readLine();
emit IHM_text(ligne);
}
QTextStream text(clientConnection);
}
ManinWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QObject::connect(&server,SIGNAL(IHM_connetion()),this,SLOT(connectionRequested()));
QObject::connect(&server,SIGNAL(read(QString)),this,SLOT(print_text(QString)));
}
void MainWindow::on_quitButton_clicked()
{
qApp->quit();
}
void MainWindow::print_text(QString text){
ui->log->append("message : " + text);
}
void MainWindow::connectionRequested(){
ui->log->append("connection OK!");
}
MainWindow::~MainWindow()
{
delete ui;
}
You have a typo in connect method: IHM_connetion
QObject::connect(&server,SIGNAL(**IHM_connetion**())
while the emitted signal is:
emit IHM_connection()
QObject:connect returns a bool value which indicates if signal-slot connection was successful. Checking this value (for example, with Q_ASSERT) is a good practice and can save you a lot of time in case of typos like this. .