I am using QNetworkAccessManager in function, which is run periodically by QTimer. The code is:
QTimer* timer=new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(findUpdate()));
timer->setSingleShot(false);
timer->start(frequency*1800000);
void MainWindow::findUpdate()
{
for (int i=0;i<aplikace.count();i++){
QNetworkAccessManager* manager=new QNetworkAccessManager(this);
connect(manager,SIGNAL(finished(QNetworkReply*)),this,SLOT(checkUpdate(QNetworkReply*)));
manager->get(QNetworkRequest(QUrl("http://www.gibucsoft.8u.cz/"+lang+"gibuclauncher/verze.php?ver="+aplikace.at(i))));
}
}
The compilation is fine and when I run my application from the Qt Creator it is OK as well but when I run it from the OS the program falls after a while (but not long enough for the timer to even start the function findUpdate). Sometimes before falling this error message shows:
This application has requested the Runtime to terminate it in an unusual way. Please contact the application's support team for more information.
Related
I want to use a recursive procedure to iterate through a large number of images in Qt: essentially the image is repeatedly quartered (up to a limit) and the user is asked whether the image passes or fails - ie if the image passes at large dimensions we call our function again with smaller dimensions (until we reach the limit), if it fails we return and so pass back up the hierarchy.
This approach seems to run into a roadblock with Qt's event-driven approach - I cannot see how I can pause the loop while waiting for the user input - ie there is nothing like a "wait_for_button_press" method.
I know that this sort of approach is regarded as an anti-pattern in event driven programming, but what is the alternative way that doesn't involve holding lots and lots of state on the heap (as opposed to getting it held for 'free' on the stack)?
QEventLoop maybe could help you. I start a http connection aside a timer with a timeout, all inside a thread. Then a wait for one of those had finish and return.
void MyThread::run(){
QNetworkAccessManager qnaManager;
bool isPost = false;
QUrl url(myUrl);
QNetworkRequest req(url);
QNetworkReply *reply;
req.setHeader(QNetworkRequest::ContentTypeHeader,
"application/json");
req.setHeader(QNetworkRequest::ContentLengthHeader,
QVariant(postData.size()).toString());
reply = qnaManager.get(req);
QEventLoop eventLoop;
QTimer timer;
timer.setSingleShot(true);
const int timeout = 400;
timer.start(timeout);
connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
connect(reply, SIGNAL(finished()), &eventLoop, SLOT(quit()));
eventLoop.exec();
if (timer.isActive()){
//everything is ok
}else{
//timer elapsed, no replay
return;
}
}
For what it's worth, in the end I decided that the best route was to implement more message passing code - wait for the user input to dispatch a message. It was longer code than if I had used/had available the 'traditional' call back type paradigm, but it worked cleanly in the end.
I am writing an application to request a web page at equal intervals in order to get any changes in it (to check whether new data is received). here how i did it.
private:
QNetworkReply *r;
QNetworkAccessManager *m;
QNetworkRequest request;
QTimer *timer;
in the constructor ,
m = new QNetworkAccessManager(this);
timer = new QTimer(this);
connect(r , SIGNAL(readyRead()), this , SLOT(readit()));
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(1000);
readit function,
void MainWindow::readit(){
QString st;
st=r->readAll();
m->deleteResource(request);
ui->textBrowser->append(st);
}
update function,
void MainWindow::update()
{
request.setUrl(QUrl("http://localhost/test/default.php"));
r = m->get(request);
}
my problem is m->get(request) gets the request at its first call only, when it is called again it does nothing. I did several experiments but end up with no success results. i changed the second request to another web page using a button click but it did nothing too.
So I need help from an expert how to update the get request and get new reply multiple times.
and also i want to know am i doing a correct thing or is there mo reliable methods to get data on data change from the server than checking for the website at regular intervals.
I see following problems:
readyRead fires an arbitrary number of times per request - including zero times (!), but you treat it as if it fired exactly once. Use the finished signal, which is does what you want: fires once, no more, no less.
The update slot doesn't connect any slots to the request.
I am trying to implement a login timeout when the username/password has been entered wrong too many time. But i am unable to do so. My code is below
ui->label->setText("Password entered wrong too many times, entered 10 minute cooldown period");
QTimer *timer = new QTimer(this);
connect(timer, SIGNAL(timeout()), this, SLOT(update()));
timer->start(6000);
ui->pushButton->setVisible(false);
if(!timer->isActive())
ui->pushButton->setVisible(true);
Try this
ui->pushButton->hide();
QTimer::singleShot(5000, ui->pushButton, SLOT(show()));
I'm trying to have an QTimer object count in intervals, continuously to call a function. I followed an example and I have set the intervals but it doesn't appear to start counting ever again.
This is the piece of code I'm working with
QTimer *timer = new QTimer(this);
timer->setInterval(1000);
connect(timer, SIGNAL(timeout()), this, SLOT(MyFunction()));
timer->start();
Is your main loop stil running?
Does the object you reference with "this" is stil existent?
Could you check if the timer is set to single shot?
sorry didn't have the function set to a slot in the header file that was the problem
private slot:
void MyFunction();
Im making a connection every X sec. but in case net bandwidth is overloaded timer fires before QNetworkAccessManager sends finished signal and app crashes.
MainWindow::construct:
pTimer = new QTimer(this);
connect(pTimer, SIGNAL(timeout()), this, SLOT(connect()));
pTimer->start(5000);
MainWindow::connect()
pNetworkManager = new QNetworkAccessManager(this);
connect(pNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(result(QNetworkReply*)));
pNetworkManager->get(QNetworkRequest(url));
MainWindow::result(QNetworkReply *reply) processes the response
how to check if QNetworkAccessManager isFinished before timer fires again?
Don't create a network manager per request, but only one network manager for your class. Otherwise you leak managers with each request until the mainwindow is destroyed.
QNetworkManager::get returns the pointer to the QNetworkReply representing the request. You can store that reply in a QPointer, connect to its signals, check QNetworkReply::isFinished() etc. to track whether the request is still running or not.
Why not simply launch timer after request finished?
pTimer = new QTimer(this);
pTimer->setSingleshot(true);
connect(pTimer, SIGNAL(timeout()), this, SLOT(connect()));
pTimer->start(5000);
pNetworkManager = new QNetworkAccessManager(this);
connect(pNetworkManager, SIGNAL(finished(QNetworkReply*)), this, SLOT(result(QNetworkReply*)));
connect(pNetworkManager, SIGNAL(finished(QNetworkReply*)), pTimer, SLOT(start()));