qt creator - MainWindow from code from the main.cpp in Qt -


want understand difference in code between mainwindow , main.cpp. specifically, how chunk of code written exclusively in main.cpp needs modified part of mainwindow.cpp , mainwindow.h.

as example, trying modify code fine answer work in mainwindow.

main.cpp

#include <qtwidgets> #include <qtnetwork>  int main(int argc, char *argv[]) {     qapplication a(argc, argv);     //setup gui (you doing in designer)     qwidget widget;     qformlayout layout(&widget);     qlineedit lineeditname;     qlineedit lineeditgender;     qlineedit lineeditregion;     auto edits = {&lineeditname, &lineeditgender, &lineeditregion};     for(auto edit : edits) edit->setreadonly(true);     layout.addrow("name:", &lineeditname);     layout.addrow("gender:", &lineeditgender);     layout.addrow("region:", &lineeditregion);     qpushbutton button("get name");     layout.addrow(&button);      //send request uinames api     qnetworkaccessmanager networkmanager;     qobject::connect(&networkmanager, &qnetworkaccessmanager::finished,                  [&](qnetworkreply* reply){         //this lambda called when reply received         //it can slot in gui window class         //check errors         if(reply->error() != qnetworkreply::noerror){             for(auto edit : edits) edit->settext("error");             networkmanager.clearaccesscache();         } else {             //parse reply json , display result in ui             qjsonobject jsonobject=     qjsondocument::fromjson(reply->readall()).object();             qstring fullname= jsonobject["name"].tostring();             fullname.append(" ");             fullname.append(jsonobject["surname"].tostring());             lineeditname.settext(fullname);             lineeditgender.settext(jsonobject["gender"].tostring());             lineeditregion.settext(jsonobject["region"].tostring());         }         button.setenabled(true);         reply->deletelater();         });      //url parameters     qurlquery query;     query.addqueryitem("amount", "1");     query.addqueryitem("region", "united states");     qurl url("http://uinames.com/api/");     url.setquery(query);     qnetworkrequest networkrequest(url);     //send request when button clicked     qobject::connect(&button, &qpushbutton::clicked, [&](){         networkmanager.get(networkrequest);         button.setenabled(false);         for(auto edit : edits) edit->settext("loading. . .");     });      widget.show();     return a.exec(); } 

edit

added timer part of same answer; please demonstrate how version timer can done well

qtimer timer; qobject::connect(&timer, &qtimer::timeout, [&](){     networkmanager.get(networkrequest);     button.setenabled(false);     for(auto edit : edits) edit->settext("loading. . ."); }); timer.start(60000); //60000 msecs = 60 secs 

i struggle modifying networkmanager class members, how structure code , how replace lambda functions.

if can provide required modifications me gain better understanding great.

you want separate out user interface , controller (business logic) separate classes.

the body of main() instantiates ui , controller , connects them. timer fetches new results every 5 seconds. timer rolled controller, - show separated out example of adding functionality existing class without modifying it.

main.cpp

// https://github.com/kubao/stackoverflown/tree/master/questions/into-mainwin-39643510 #include "mainwindow.h" #include "controller.h"  int main(int argc, char *argv[]) {    qapplication app{argc, argv};    mainwindow ui;    controller ctl;    qtimer timer;    timer.start(5*1000);    qobject::connect(&timer, &qtimer::timeout, &ctl, &controller::get);     qobject::connect(&ctl, &controller::busy, &ui, [&]{ ui.setstate(mainwindow::loading); });    qobject::connect(&ui, &mainwindow::request, &ctl, &controller::get);    qobject::connect(&ctl, &controller::error, &ui, [&]{ ui.setstate(mainwindow::error); });    qobject::connect(&ctl, &controller::values, &ui, &mainwindow::setfields);    ui.show();    return app.exec(); } 

the controller knows nothing of user interface, , deals processing requests only. emits busy signal every time request starts being processed.

if wanted provide better feedback multiple active requests, busy signal need emitted when there no requests pending , new 1 added, , idle signal emitted when last request has finished , there no more pending ones.

controller.h

#ifndef controller_h #define controller_h  #include <qtnetwork>  class controller : public qobject {    q_object    qnetworkaccessmanager manager{this};    qnetworkrequest request;    q_slot void onreply(qnetworkreply *); public:    explicit controller(qobject * parent = nullptr);    q_slot void get();    q_signal void busy();    q_signal void error(const qstring &);    q_signal void values(const qstring & name, const qstring & gender, const qstring & region); };  #endif // controller_h 

controller.cpp

#include "controller.h"  controller::controller(qobject *parent) : qobject(parent) {    qurlquery query;    query.addqueryitem("amount", "1");    query.addqueryitem("region", "united states");    qurl url("http://uinames.com/api/");    url.setquery(query);    request = qnetworkrequest(url);    connect(&manager, &qnetworkaccessmanager::finished, this, &controller::onreply); }  void controller::onreply(qnetworkreply * reply) {    if (reply->error() != qnetworkreply::noerror) {       emit error(reply->errorstring());       manager.clearaccesscache();    } else {       //parse reply json , display result in ui       auto jsonobject = qjsondocument::fromjson(reply->readall()).object();       auto fullname = jsonobject["name"].tostring();       fullname.append(" ");       fullname.append(jsonobject["surname"].tostring());       emit values(fullname, jsonobject["gender"].tostring(), jsonobject["region"].tostring());    }    reply->deletelater(); }  void controller::get() {    emit busy();    manager.get(request); } 

the user interface knows nothing of business logic, provides api that's sufficient business logic use it. can in 1 of 3 states: normal state results visible, loading state busy feedback shown, , error state error information shown. setfields slot returns state normal.

mainwindow.h

#ifndef mainwindow_h #define mainwindow_h  #include <qtwidgets>  class mainwindow : public qwidget {   q_object   qformlayout layout{this};   qlineedit lineeditname;   qlineedit lineeditgender;   qlineedit lineeditregion;   qpushbutton button{"get name"};   qlineedit * edits[3] = {&lineeditname, &lineeditgender, &lineeditregion}; public:   enum state { normal, loading, error };   explicit mainwindow(qwidget * parent = nullptr);   q_slot void setfields(const qstring & name, const qstring & gender, const qstring & region);   q_slot void setstate(state);   q_signal void request(); };  #endif // mainwindow_h 

mainwindow.cpp

#include "mainwindow.h"  mainwindow::mainwindow(qwidget *parent) : qwidget(parent) {    for(auto edit : edits) edit->setreadonly(true);    layout.addrow("name:", &lineeditname);    layout.addrow("gender:", &lineeditgender);    layout.addrow("region:", &lineeditregion);    layout.addrow(&button);    connect(&button, &qpushbutton::clicked, this, &mainwindow::request); }  void mainwindow::setfields(const qstring & name, const qstring & gender, const qstring & region) {    setstate(normal);    lineeditname.settext(name);    lineeditgender.settext(gender);    lineeditregion.settext(region); }  void mainwindow::setstate(mainwindow::state state) {    if (state == normal) {       (auto edit : edits) edit->setenabled(true);       button.setenabled(true);    }    else if (state == loading) {       (auto edit : edits) edit->setenabled(false);       button.setenabled(false);    }    else if (state == error) {       (auto edit : edits) edit->settext("error...");       button.setenabled(true);    } } 

Comments

Popular posts from this blog

angular - Is it possible to get native element for formControl? -

unity3d - Rotate an object to face an opposite direction -

javascript - Why jQuery Select box change event is now working? -