I want to pass data from one form to another. I did some research and I found out how to do it, but my code doesn't work!!
Here is my code:
MainWindow.h
signals:
void signalEmission(const String &port) ;
MainWindow.cpp
void MainWindow::on_pushButtonclicked()
{
emit signalEmission(nameArea->toPlainText()) ;
}
class.h
private slots:
void mySlot(const QString &port) ;
class.cpp
void class::mySlot(const QString &port)
{
messages->append(port) ;
}
main.cpp
MainWindow h ;
class c;
QObject::connect(&h,SIGNAL(signalEmission(const QString&)),&c,SLOT(research(const QString&))) ;
I don't get the port number from the MainWindow class!!
Can someone please help.
EDIT:
Here is my code
history.h
#ifndef HISTORY_H
#define HISTORY_H
#include <QMainWindow>
#include <ui_history.h>
#include <QTcpSocket>
class History : public QMainWindow, private Ui::History
{
Q_OBJECT
public:
explicit History();
private slots:
void on_searchButton_clicked();
signals:
void signalEmission( QString port) ;
};
#endif // HISTORY_H
history.cpp
#include "history.h"
#include "ui_history.h"
#include "client.h"
#include "ui_client.h"
#include <QDebug>
#include <QtNetwork>
History::History() {
setupUi(this);
resize(500,200);
move(300,300) ;
}
void History::on_searchButton_clicked()
{
emit this->signalEmission(receiverPort->toPlainText()) ;
this->close() ;
}
client.h
#ifndef HEADER_CLIENT
#define HEADER_CLIENT
#include <QMainWindow>
#include <QtWidgets>
#include <QtNetwork>
#include <QSqlDatabase>
#include "history.h"
#include "ui_client.h"
class client : public QMainWindow, private Ui::client
{
Q_OBJECT
public:
explicit client();
public slots:
void on_connexionButton_clicked();
void on_sendButton_clicked();
void receivedData();
void connectClient();
void disconnect();
void socketError(QAbstractSocket::SocketError erreur);
void on_disconnexionButton_clicked();
void on_connectedClientsButton_clicked();
void on_refreshButton_clicked();
void on_historyButton_clicked();
void research( QString port) ;
private slots:
void on_clearButton_clicked();
void on_connectedList_pressed();
private:
QTcpSocket *socket; // Représente le serveur
quint16 messageLength;
History *his;
QSqlDatabase db ;
QStringList *cc ;
QStringListModel *ccl ;
QString selectedTexts ;
};
#endif
client.cpp
#include "client.h"
#include "history.h"
#include "ui_history.h"
#include "ui_client.h"
#include <QMainWindow>
#include <QSqlDatabase>
#include <QSqlError>
#include <QSqlQuery>
#include <QDebug>
client::client()
{
setupUi(this);
cc = new QStringList();
ccl = new QStringListModel() ;
socket = new QTcpSocket(this);
connect(socket, SIGNAL(readyRead()), this, SLOT(receivedData()));
connect(socket, SIGNAL(connected()), this, SLOT(connectClient()));
connect(socket, SIGNAL(disconnected()), this, SLOT(disconnect()));
connect(socket, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(socketError(QAbstractSocket::SocketError)));
messageLength = 0;
disconnexionButton->setEnabled(false);
connectedClientsButton->setEnabled(false);
sendButton->setEnabled(false);
clearButton->setEnabled(false);
refreshButton->setEnabled(false);
historyButton->setEnabled(false);
}
void client::research(QString port){
qDebug() << port ;
//messagesList->cleanHistory() ;
/* QSqlQuery qry(db);
qry.prepare("SELECT * FROM conversations where sender=? and receiver=?");
qry.addBindValue(socket->localPort()) ;
qry.addBindValue(port) ;
if(!qry.exec()){
qDebug() << "Problem with Select conversation" ;
}
else{
qDebug() << "Select conversation query executed successfully" ;
}
messagesList->append(tr("<strong>Historique des conversations:</strong>")) ;
while(qry.next())
{
messagesList->append(qry.value(2).toString()+" "+qry.value(3).toString()) ;
}*/
}
Can someone please tell me what's wrong. It's driving me crazy!!
There are so many little issues here, looking at the comments, this code does not appear to be the real code anyway...? it is better to post the real code then to send some very buggy example - it will confuse people trying to help you.
Anyway, a few things to try to help you:
Is your class "class" really called "class"?, this is a key word
already, so I would rename that, I have no idea what the compiler will make of that :o
Make sure all the function signatures are identical for your slots and signals, i.e. they all take "const QString &".
Check the connection return value is true (ok) and not false (failed):
if (!QObject::connect(...)) {printf("Connection failed!\n");}. If its false then something is wrong.
Try a simple start-point, i.e. make a slot and signal that take a QString such that:
void MainWindow::on_pushButtonclicked()
{
emit signalEmission((QString) "test");
}
finally, please show any errors/warnings from compilation and from debug output.
Related
so i am writing a simple video player program and i did the same steps as the lesson i am taking but when i run the program and click on functionalities like end (which is close()) and open (open file) they dont work, i used the slot triggering as per the lesson although i saw different ways of using the menubar here but i must follow this format, here is my code:
header:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QPushButton>
#include <QVideoWidget>
#include <QStyle>
#include <QMediaPlayer>
#include <QFileDialog >
namespace Ui {
class videoWidget;
}
class videoWidget : public QMainWindow
{
Q_OBJECT
QMediaPlayer *meinPlayer;
QPushButton *playButton;
QPushButton *stopButton;
public:
explicit videoWidget(QWidget *parent = 0);
~videoWidget();
private slots:
void listeUndTitelAktualisieren();
void on_action_End_triggered();
void on_action_ffnen_triggered();
void on_action_Stop_triggered();
void on_action_PlayBack_triggered();
void on_action_Pause_triggered();
private:
Ui::videoWidget *ui;
};
#endif // MAINWINDOW_H
cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
videoWidget::videoWidget(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::videoWidget)
{
ui->setupUi(this);
meinPlayer = new QMediaPlayer(this);
meinPlayer->setMedia(QUrl::fromLocalFile("/beispiele/topologien.wmv"));
meinPlayer->play();
}
void videoWidget::listeUndTitelAktualisieren()
{
QString titel = meinPlayer->media().canonicalUrl().toLocalFile();
ui->listWidget->addItem(titel);
this->setWindowTitle("Multimedia-Player – " + titel);
connect(meinPlayer, SIGNAL(mediaChanged(QMediaContent)), this, SLOT(listeUndTitelAktualisieren()));
}
void videoWidget::on_action_End_triggered()
{
this->close();
}
void videoWidget::on_action_ffnen_triggered()
{
QFileDialog *meinDialog = new QFileDialog(this);
meinDialog->setAcceptMode(QFileDialog::AcceptOpen);
meinDialog->setWindowTitle("Datei öffnen");
meinDialog->setNameFilters(QStringList() << "Videos (*.mp4 *.wmv)" << "Audios (*.mp3)" << "Alle Dateien (*.*)");
meinDialog->setDirectory(QDir::currentPath());
meinDialog->setFileMode(QFileDialog::ExistingFile);
if (meinDialog->exec() == QDialog::Accepted) {
QString datei = meinDialog->selectedFiles().first();
meinPlayer->setMedia(QUrl::fromLocalFile(datei));
/*QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"), "/home/jana", tr("Video & Audio Files (*.mp3 *.mp4 *.wmv)"));
*/
meinPlayer->play();
}
}
void videoWidget::on_action_Stop_triggered()
{
meinPlayer->pause();
}
void videoWidget::on_action_PlayBack_triggered()
{
meinPlayer->play();
}
void videoWidget::on_action_Pause_triggered()
{
meinPlayer->pause();
}
am pretty sure this instruction here:
connect(meinPlayer, SIGNAL(mediaChanged(QMediaContent)), this, SLOT(listeUndTitelAktualisieren()));
is not located where it should coz you are connecting the signal toa slot INSIDE of the SLOT implementation....
try moving that to the constructor of dein videoWidget
I am making a multiple game. I need to take command from client. This means I have GUI and TcpServer. So I need to work them simultaneously. I used Thread but it doesnt work. Could you please help me to find the problem?
Summarizing: Firstly player press the "online" button. Then Oyun() Gui function runs and button connected with connectPressed() function. In this function there is a thread in order to run read the client commands when Gui is working.
Firstly I used QTimer in order to take command from Client in every 1 second. But My GUI freezed. And Then I used QThread but according to my research, QThread is not proper for GUI app. So I found Qtconcurrent, QFutureWatcher and QFuture. But my thread is still not working. I should have made a mistake somewhere.
#include <QApplication>
#include <anaclass.h>
#include <player2.h>
#include <tcpserver.h>
#include <QThread>
#include <QObject>
//#include <worker.h>
AnaClass *anaclass;
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
anaclass = new AnaClass();
anaclass->show();
anaclass->Giris(); //button selection page
return a.exec();
}
#include "anaclass.h"
Puan *puanlama1;
Puan *puanlama2;
player2 *yilan2;
AnaClass::AnaClass() : QGraphicsView()
{
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOn);
setFixedSize(800,600);
scene = new QGraphicsScene;
scene->setSceneRect(0,0,800,600);
setScene(scene);
}
void AnaClass::Giris()
{
connectButton = new Button("Online");
double cxPos = this->width()/2 - connectButton->boundingRect().width()/2;
double cyPos= 425;
connectButton->setPos(cxPos, cyPos);
connect(connectButton, SIGNAL(clicked()), this, SLOT(connectPressed()));
scene->addItem(connectButton);
}
void AnaClass::Oyun()
{
scene->clear();
puanlama1 = new Puan();
puanlama1->setDefaultTextColor(Qt::blue);
puanlama1->setPos(5, 2);
scene->addItem(puanlama1);
yilan = new Yilan();
yilan->setRect(0,0,19,19);
scene->addItem(yilan);
yilan->setFlags(QGraphicsItem::ItemIsFocusable);
yilan->setFocus();
QBrush brush;
brush.setStyle(Qt::SolidPattern);
brush.setColor(Qt::blue);
yilan->setBrush(brush);
if(stringButtonName == "Player2" || stringButtonName == "Online")
{
yilan->setPos(scene->width()/2 + 60, scene->height()/2);
}
else
{
yilan->setPos(scene->width()/2, scene->height()/2);
}
if(stringButtonName == "Player2" || stringButtonName == "Online")
{
yilan->playerNumber=1;
puanlama2 = new Puan();
puanlama2->setDefaultTextColor(Qt::green);
puanlama2->setPos(700, 2);
scene->addItem(puanlama2);
yilan2 = new player2();
yilan2->setRect(0,0,19,19);
scene->addItem(yilan2);
yilan2->setFlags(QGraphicsItem::ItemIsFocusable);
yilan2->setFocus();
QBrush brush2;
brush2.setStyle(Qt::SolidPattern);
brush2.setColor(Qt::green);
yilan2->setBrush(brush2);
yilan2->setPos(scene->width()/2 - 60,scene->height()/2);
}
emit emitTcp();
}
void AnaClass::connectPressed()
{
qDebug()<<"connect basildi";
server = new TCPServer();
server->Test();
stringButtonName = connectButton->buttonName;
qDebug()<<"Gelen Veri " + server->OkunanBilgi;
QFutureWatcher<void> watcher;
connect(&watcher, SIGNAL(finished()), server, SLOT(daimaOku()), Qt::QueuedConnection);
QFuture<void> deneme = QtConcurrent::run(this, &AnaClass::emitTcp);
watcher.setFuture(deneme);
Oyun();
}
}
#ifndef ANACLASS_H
#define ANACLASS_H
#include <QGraphicsScene>
#include <QGraphicsView>
#include <yilan.h>
#include <Meyve.h>
#include <QBrush>
#include <Puan.h>
#include <player2.h>
#include <QThread>
#include <label.h>
#include <QKeyEvent>
#include <button.h>
#include <QDebug>
#include <tcpserver.h>
#include <QTime>
#include <QTimer>
#include <QMutex>
//#include <worker.h>
#include <QFuture>
#include <QtConcurrent>
#include <QFutureWatcher>
class AnaClass : public QGraphicsView
{
Q_OBJECT
public:
AnaClass();
void Giris();
void Oyun();
void timerEvent(QTimerEvent *event);
void keyPressEvent(QKeyEvent *event2);
public:
Yilan *yilan;
//QThread *thread;
QGraphicsScene *scene;
Label *label1;
Button* player1Button;
Button* player2Button;
Button* connectButton;
TCPServer *server;
QTimer *timerOnline;
public:
int k=0;
int t=0;
QString stringButtonName;
signals:
void emitTcp();
public slots:
void connectPressed();
void player1Pressed();
void player2Pressed();
};
#endif // ANACLASS_H
#define TCPSERVER_H
#include <QTcpServer>
#include <QTcpSocket>
#include <QDebug>
#include <QObject>
#include <QTimer>
class TCPServer : public QObject
{
Q_OBJECT
public:
TCPServer(QObject* parent = nullptr);
void Test();
signals:
//void emitTcp();
public slots:
void newConnection();
void daimaOku(); // always read as english
public:
QTcpServer *server;
QTcpSocket *socket;
QTimer *timerTcp;
QString OkunanBilgi;
};
#endif // TCPSERVER_H
#include "tcpserver.h"
TCPServer::TCPServer(QObject * parent) : QObject()
{
}
void TCPServer::Test()
{
server = new QTcpServer();
connect(server, SIGNAL(newConnection()), this, SLOT(newConnection()));
if(!server->listen(QHostAddress::Any, 1234))
{
qDebug()<<"server baslamadi";
}
else
{
qDebug()<<"server basladi";
}
//timerTcp = new QTimer();
//connect(timerTcp, SIGNAL(timeout()), this, SLOT(daimaOku()));
//emit emitTcp();
}
void TCPServer::newConnection()
{
qDebug()<<"newconnection";
socket = server->nextPendingConnection();
socket->write("Merhaba Client");
socket->flush();
socket->waitForBytesWritten(5000);
timerTcp->start(50);
}
void TCPServer::daimaOku() //alwaysread() as english
{
qDebug()<<"always read function is working";
// if(socket->state() == QAbstractSocket::ConnectedState)
// {
// qDebug()<<"Daima oku fonsiyonu soket bagli";
// socket->waitForReadyRead();
// OkunanBilgi = socket->readAll();
// qDebug()<<"Tcp daima oku :" + OkunanBilgi;
// }
}
Thank you for your comments. I solved the problem by deleting QFuture and adding connect() like below.
timerOnline = new QTimer();
connect(timerOnline, SIGNAL(timeout()), server, SLOT(daimaOku()));
timerOnline->start(500);
But I have another problem. When Client connects the server, my Gui app freezes. You can find the revised code below.
void TCPServer::daimaOku()
{
qDebug()<<"Function is running";
if(socket->state() == QAbstractSocket::UnconnectedState)
{
qDebug()<<"Socket is not connected";
}
else
{
qDebug()<<"Socket connected";
socket->waitForReadyRead();
OkunanBilgi = socket->readAll();
qDebug()<<"Tcp always read :" + OkunanBilgi;
}
}
When client is not connected, the output is:
Function is running
Socket is not connected
Socket is not connected ...
I can play the game but when client is connected, game freezes. I don't understand why.
I have an issue using the connection stuff of Qt5.
I posted here some code to give a quick view:
void MainWindow::onMessage(const Message* message) {
try {
const TextMessage* textMessage = dynamic_cast<const TextMessage*> (message);
std::string text = "";
if (textMessage != NULL) {
text = textMessage->getText();
} else {
text = "NOT A TEXTMESSAGE!";
}
int fieldIndex=message->getIntProperty("field");
QString qstr = QString::fromStdString(text);
switch(fieldIndex)
{
case 0:ui->lineEdit->setText(qstr);break;
case 1:ui->lineEdit_2->setText(qstr);break;
case 2:ui->lineEdit_3->setText(qstr);break;
case 3:ui->lineEdit_4->setText(qstr);break;
case 4:ui->lineEdit_5->setText(qstr);break;
case 5:ui->lineEdit_6->setText(qstr);break;
case 6:ui->lineEdit_7->setText(qstr);break;
case 7:ui->lineEdit_8->setText(qstr);break;
case 8:ui->lineEdit_9->setText(qstr);break;
}
connect(ui->lineEdit_4,SIGNAL(textChanged(qstr)),ui->widget_diagram2,SLOT(upDateDatas(qstr)));
}catch (CMSException& e) {
e.printStackTrace();
}
}
As you can see I'm trying to connect the signal textChanged generated by the lineEdit_4 with the ui object widget_diagram2 and execute the slot upDateDatas(qstr). But something bad happens, because I received this message:
QObject::connect: No such signal QLineEdit::textChanged(qstr) in mainwindow.cpp:97
QObject::connect: (sender name: 'lineEdit_4')
QObject::connect: (receiver name: 'widget_diagram2')
personally I don't know why....where is the error?
void MainWindow::upDateDatas(QString qstr){
bool ok;
double value0=qstr.toDouble(&ok);
double key = QDateTime::currentDateTime().toMSecsSinceEpoch()/1000.0;
static double lastPointKey = 0;
if (key-lastPointKey > 0.01) // at most add point every 10 ms
{
ui->widget_diagram2->graph(0)->addData(key, value0);
ui->widget_diagram2->graph(0)->removeDataBefore(key-8);
ui->widget_diagram2->graph(0)->rescaleValueAxis();
lastPointKey = key;
}
ui->widget_diagram2->xAxis->setRange(key+0.25, 8, Qt::AlignRight);
//ui->widget_diagram2->replot();
}
and this is the error:
QObject::connect: No such slot QCustomPlot::upDateDatas(QString) in mainwindow.cpp:97
QObject::connect: (sender name: 'lineEdit_4')
QObject::connect: (receiver name: 'widget_diagram2')
.h file:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QTimer>
#include <activemq/library/ActiveMQCPP.h>
#include <decaf/lang/Thread.h>
#include <decaf/lang/Runnable.h>
#include <decaf/util/concurrent/CountDownLatch.h>
#include <decaf/lang/Integer.h>
#include <decaf/lang/Long.h>
#include <decaf/lang/System.h>
#include <activemq/core/ActiveMQConnectionFactory.h>
#include <activemq/util/Config.h>
#include <cms/Connection.h>
#include <cms/Session.h>
#include <cms/TextMessage.h>
#include <cms/BytesMessage.h>
#include <cms/MapMessage.h>
#include <cms/ExceptionListener.h>
#include <cms/MessageListener.h>
#include "qcustomplot.h"
#include "IfacomAmqReceiver.h"
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow, public MessageListener
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
void connectionReceiver();
void onMessage(const Message*);
void setupDiagram();
IfacomAmqReceiver* m_IfacomAmqListener;
private:
Ui::MainWindow *ui;
private slots:
void upDateDatas(QString);
};
#endif // MAINWINDOW_H
You call to connect() is wrong. It should be:
connect(ui->lineEdit_4, SIGNAL(textChanged(QString)),
ui->widget_diagram2, SLOT(upDateDatas(QString)));
Pay attention that inside connect you should pass types rather then variables names. Constant references const type & are OK, but ideally should be elided to yield type - it saves on typing, and is what connect internally does anyway.
I have a login window where users input some text.
login.cpp:
#include "login.h"
#include "ui_login.h"
#include "mainwindow.h"
login::login(QWidget *parent) :
QDialog(parent),
ui(new Ui::login)
{
ui->setupUi(this);
this->setFixedSize(320,212);
connect(ui->_login, SIGNAL(clicked()), this, SLOT(rLogin()));
connect(ui->_close, SIGNAL(clicked()), this, SLOT(rClose()));
}
login::~login()
{
delete ui;
}
void login::rLogin()
{
prefix = ui->_prefix->text();
site = ui->_site->text();
dbname = ui->_database->text();
user = ui->_username->text();
QString pass = ui->_password->text();
QSqlDatabase db = QSqlDatabase::addDatabase("QMYSQL");
db.setHostName(site);
db.setDatabaseName(prefix + dbname);
db.setUserName(prefix + user);
db.setPassword(pass);
bool logged = db.open();
if (logged) {
rOpen();
} else {
int warning = QMessageBox::warning(this, tr("Hostel ERP Error"),
tr("Could not connect to database.\n"
"Please check your inputs."),
QMessageBox::Ok);
}
}
void login::rOpen()
{
mainwindow* openwindow = new mainwindow();
openwindow->show();
this->close();
}
void login::rClose()
{
this->close();
}
prefix, site, dbname, and user are defined as QString in login.h
login.h:
#ifndef LOGIN_H
#define LOGIN_H
#include <QDialog>
namespace Ui {
class login;
}
class login : public QDialog
{
Q_OBJECT
public:
explicit login(QWidget *parent = 0);
void rOpen();
QString prefix;
QString site;
QString dbname;
QString user;
~login();
I am trying to access prefix, site, dbname, and user from mainwindow.cpp
mainwindow.h:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QSql>
#include <QSqlDatabase>
#include <QSqlQuery>
#include <QMessageBox>
#include <QPushButton>
#include <QAction>
#include <QMainWindow>
#include <QSqlRecord>
#include <login.h>
namespace Ui {
class mainwindow;
}
class mainwindow : public QMainWindow
{
Q_OBJECT
public:
explicit mainwindow(QWidget *parent = 0);
void rPopulate();
QPushButton *button;
login * log;
~mainwindow();
mainwindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "login.h"
#include "newbooking.h"
#include <qaction.h>
//somecode
login *log = new login;
QString table_schema = log->prefix + log->dbname;
however both log->prefix and log->dbname are empty. There is default text in ui->_prefix->text(); and ui->_database->text(); so they shouldn't be empty.
You are likely trying to access mainwindow::log i.e the log that is a member of mainwindow. You probably call rLogin on this function.
However you are getting empty values because you are creating a new object which has default values.
login *log = new login;
This line is part of the problem I assume. We wont know more before you show us how you call rLogin, but you want to check from the same object that you call it on.
Needed to declare QString as global var at the top of login.h in between #include "mainwindow.h" and login::login(QWidget *parent):, then in login.cpp define the QStrings.
eg. login.h
#include ...
extern QString site; //this
login::login(QWidget *parent) :
login.cpp
#include ...
QString example; //this
login::login(QWidget *parent) :
after that you can simply call them from whatever file you want. Silly me.
I am working with Qt creator to make a GUI program that takes in different URLs and will download and display the html code.
The user can add different URLs to a listWidget. Then the user can select a specific URL and download the html which will be displayed beside the list of URLs.
The problem I am having is getting the text area to update after the reply is received.
main.cpp - Basically just shows the window.
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "htmlmanager.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
mainwindow.h - Pretty straight forward. Contains the object html that will be used to request the html from the inputted website.
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "htmlmanager.h"
#include <QString>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
HtmlManager html;
private slots:
void on_addButton_clicked();
void on_actionExit_triggered();
void on_removeButton_clicked();
void on_downloadButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
mainwindow.cpp - This is the beginning of the problem. If you look down at the "downloadButton_clicked()" function, you see that it fetches the html by sending a request. However, the reply isn't recieved before the next line so the text field is set to "".
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_addButton_clicked()
{
if(!ui->lineEdit->text().isEmpty())
{
ui->listWidget->addItem(ui->lineEdit->text());
}
else
{
qDebug() << "Input field is empty.";
}
}
void MainWindow::on_actionExit_triggered()
{
//doesn't do anything right now
}
void MainWindow::on_removeButton_clicked()
{
if(ui->listWidget->currentItem()) //If an item is selected
{
delete ui->listWidget->currentItem();
}
else
{
qDebug() << "No selection";
}
}
void MainWindow::on_downloadButton_clicked()
{
if(ui->listWidget->currentItem()) //If an item is selected
{
html.fetch(ui->listWidget->currentItem()->text());
ui->textBrowser->setText(html.str);
}
else
{
qDebug() << "No selection";
}
}
htmlmaneger.h
#ifndef HTMLMANAGER_H
#define HTMLMANAGER_H
#include <QObject>
#include <QDebug>
#include <QtNetwork>
#include <QNetworkReply>
#include <QNetworkAccessManager>
#include <QString>
class HtmlManager : public QObject
{
Q_OBJECT
public:
HtmlManager();
void fetch(QString Url);
QString str;
public slots:
void replyFinished(QNetworkReply* pReply);
private:
QNetworkAccessManager* m_manager;
};
#endif // HTMLMANAGER_H
htmlmanager.cpp - Once the reply is received, it stores the html in the QString "str"
#include "htmlmanager.h"
HtmlManager::HtmlManager()
{
m_manager = new QNetworkAccessManager(this);
connect(m_manager, SIGNAL(finished(QNetworkReply*)), this, SLOT(replyFinished(QNetworkReply*)));
}
void HtmlManager::fetch(QString Url)
{
m_manager->get(QNetworkRequest(QUrl(Url)));
qDebug() << "Sending network request.";
}
void HtmlManager::replyFinished(QNetworkReply* pReply)
{
qDebug() << "Recieved network reply.";
QByteArray data=pReply->readAll();
str = data;
}
Is there an easy way to send the value of str to the MainWindow class once the reply is received, or is there a way for the onclick function to wait to update the text area until after a reply is received?
You definitely don't want to wait for a reply in your onClick() function. That will cause your program to be unresponsive until the network request comes it (which could very well take "forever").
One way to attack this would be to add a signal to your HtmlManager class. Something maybe called stringReceived. Then, in your mainwindow class you'd just need to add a line like this:
connect(html, SIGNAL(stringReceived(QString)), ui->textBrowser, SLOT(setText(QString));
QNetworkAccessManager don't provide synchronous or blocking approach. If you want to wait until reply has been received you have to go for waiting in a local event loop until reply finished signal invoked.
See the following link for turning asynchronous operation into synchronous one:
http://doc.qt.digia.com/qq/qq27-responsive-guis.html
In the section "Waiting in a Local Event Loop" they have shown an example using QNetworkAccessManager. You can use the same approach with timeout and local event loop.