How to initialize QXmlStreamWriter with QString as member variable? - c++

I have implemented my own xml writer to generate xml as QString.
i have create a class "MyXmlWriter" with private member variable as QXmlStreamWriter and try to initialize it in the public method writeToString()
in declaration header file:
class MyXmlWriter {
public:
MyXmlWriter();
~MyXmlWriter();
QString writeToString();
private:
QXmlStreamWriter writer;
void writePart();
}
in cpp file:
void MyXmlWriter::writePart() {
// i want to use the QXmlStreamWriter instance hier
}
QString MyXmlWriter::writeToString(){
QString result;
writer(&result); // at this became the error: no match for call to '(QXmlStreamWriter) (QString*)'
xmlWriter.setAutoFormatting(true);
// private method called
writePart();
return result;
}
this error appear on build:
error: no match for call to (QXmlStreamWriter) (QString) writer(&result); *
If the QXmlStreamWriter write is declared in the local method writeToString() then i cant access this writer in private method writePart()
i want to use the member variable "writer" in other methods that's why a local declaration isn't an option for me.

You have to assign a new object to your variable writer, like this:
QString MyXmlWriter::writeToString() {
QString result;
writer = QXmlStreamWriter(&result); // will not compile
return result;
}
This code is dangerous. result is destroyed at the end of writeToString(), so writer then contains invalid data and you cannot use it anymore.
Additionally, QXmlStreamWriter cannot be copied, so this would probably not compile at all. It's better to just pass the QXmlStreamWriter to your methods, like this:
class MyXmlWriter {
public:
MyXmlWriter();
~MyXmlWriter();
QString writeToString();
private:
void writePart(QXmlStreamWriter &writer);
}
and
QString MyXmlWriter::writeToString() {
QString result;
QXmlStreamWriter writer(&result);
writePart(writer);
writePart(writer);
return result;
}

Related

Passing class pointer to a function

I want to use different WText instances in another function, but as I want to have just one control function, I'd like to pass them in there.
The code with current setup compiles but fails due to some memory fault which I don't understand.
class mode : public WApplication
{
//..
private:
//..
void someFunc();
void control(WText* texty);
WText* text;
WText* text2;
WText* text3;
//...etc
};
void mode::someFunc(){
control(text); //how to pass it?
//might pass text2 or text3 as well
}
void mode::control(WText* texty){
texty->setText("blabla");
//..
}
text member is a pointer to the object WText,
The first thing you need to do is a create a new WText object:
void mode::someFunc() {
text = new WText();
control(text);
}
please remember about destroy text object after use.

C++ Calling a getter method when it is not ready

I'm working on a project and it works but it is really messy so I am trying to clean it up by moving things around.
Here is a short version of the class containing the getter method
Link::Link
{
jsonUrl = QUrl("www.example.json");
QNetworkAccessManager *nam = new QNetworkAccessManager(this);
connect(nam,SIGNAL(finished(QNetworkReply*)),this,SLOT(downloadFinished(QNetworkReply*)));
QNetworkRequest request(jsonUrl);
nam->get(request)
}
void Link::downloadFinished(QNetworkReply *reply)
{
jsonArray = reply->readAll();
jsonStuff();
}
void Link::jsonStuff()
{
//does a bunch of json stuff then gets a string
string = map["url"].toString();
}
QString Link::getString()
{
return string;
}
Here is a short version of the class that calls the getter in the constructor
Header
class Commands
{
private:
Link link;
}
Source inside the constructor
Commands::Commands()
{
addCommand("!test", link.getString());
}
The problem is when I try to do it like this, I think the Commands constructor runs first and the string from the Link class is not ready yet so the string that comes out of link.getString() is empty. Is there a way to wait until the Link class finishes doing it's stuff and fills up the string before calling link.getString() inside the constructor of Commands? Not sure if this matters but most of my code is written in Qt
I hope you guys can understand what I'm trying to ask. My terminology is really poor.
Edit: Added more to my Link class
When the constructor of Commands (in this case Commands()) is called firstly it creates all variables(they are unintialized) in Commands class. That being said link is created via Link(). What you might want to do is to use jsonStuff() in the Link() constructor (it creates all member variables as well as), NOTE THAT it creates variables in this case it creates string with base costructor - it creates empty string.) Try following to fill the string:
Link() {
jsonStuff(); // string will be set
}
Or you can initialize it via initialization section:
Link() : string("Text") { }
Also you might want to return reference to string from getString() function. Reference means it doesn't create additional copy and it returns string which is stored in Link, so you can change string in a function where getString() is called. Also if it is read only you should use const reference.
Is there a way to wait until the Link class finishes doing it's stuff and fills up the string before calling link.getString() inside the constructor of Commands?
Certainly. The Link class must be a QObject that emits a signal when it has changed its properties - presumably based on the replies it got to its network request.
class Link : public QObject {
Q_OBJECT
Q_PROPERTY(QString string READ string WRITE setString NOTIFY stringChanged)
QString m_string;
public:
void jsonStuff() {
...
connect(reply, &QNetworkReply::finished, this, [this]{
...
setString(map["url"].toString());
});
}
void setString(const QString &s) {
if (m_string == s) return;
m_string = s;
emit stringChanged(m_string);
}
QString string() const { return m_string; }
Q_SIGNAL void stringChanged(const QString &);
};
You can then add the command when the link is ready:
Commands::Commands()
{
connect(&link, &Link::stringChanged, this, [this](const QString &string){
if (!string.isEmpty()) addCommand("!test", string);
});
}

QT calling functions in different sources

In my project I've created multiple gui pages. In a secondary source (secondary.cpp) I want to call a function that declared in my mainwindow.cpp. I'm not really sure how to do this.
I've tried to declare the function at public section like:
QString format (QString number);
And definition in the mainwindow.cpp like:
QString MainWindow::format(QString number)
{
...
}
Then i include #include "mainwindow.h" in my secondary source (secondary.cpp) and calling the function with lower = format(upper); but I'm getting an error message:
format was not declared in this scope.
I've also tried calling it by
lower = MainWindow::format(upper);
which gives me the error message
Cannot call member function QString MainWindown::format(Qstring)
without object.
Finaly I also tried to make a class in my mainwindow.h
class test : public QString
{
public:
QString format (QString number);
};
With QString test::format(QString number) in my mainwindow.cpp calling the function by lower = test::format(upper);
this gives me the error:
Cannot call member function QString MainWindown::format(QString)
without object.
I'm not convinced that I need to create a new class, but I thought I'd try anyway.
You need to create object of MainWindow class, then call function:
MainWindow *w = new MainWindow;
QString lower = w->format(upper);
Or another solution is static function of class. This way you have no needed create object of class and can call method by name like this:
QString lower = MainWindow::format(upper);
Of course you need to include your #include "mainwindow.h" header.
But you should know that MainWindow class is not the best place storing function for formation string, you can use QString class function like QString::toUpper() or QString::toLower() or create your own class for formating:
class myFormatingStringClass {
QString toLower(QString str);
static QStrin toUpper(QString str);
}
As i said above this way you will need to create object of myFormatingStringClass for using myFormatingStringClass::toLower() function or using static method:
QString upper = QString("Hello World");
myFormatingStringClass formating;
QString lower = formatin.toLower(upper); // Using class method of existing object
QString upper = myFormatingStringClass::toUpper(lower); // Using static method
You can't do test::format(...) to call a non-static member function.
It must be bound to an object (an instance of your class). For example, you can do this :
test testObject;
QString formattedString = testObject.format(strToFormat);

Setting a QTextStream declared in header to stdout

I am going crazy here and I promise that I have looked at the documentation.
I declare a QTextStream as a member variable in my header file, but in my constructor, I want to set it to go to stdout in my constructor.....but I can't get the syntax right to let me do it!
All I want to do is this:
QTextStream m_text_out;
m_text_out = QTextStream(stdout)........
Any help would be great!
Use an initializer list.
class MyClass {
public:
MyClass();
private:
QTextStream m_text_out;
}
MyClass::MyClass() : m_text_out(stdout) {
}

Access class function from different cpp (how to declare)

I have a problem with my Qt(c++) class.
Code:
SharedVariables.h
class SharedVariables
{
private:
QString TextoPesquisa;
bool LoginEfectuado;
public:
SharedVariables();
QString getTextoPesquisa();
void setTextoPesquisa(QString TxtPesquisa);
bool getLoginUtilizador();
void setLoginUtilizador(bool UtilizadorComLogin);
};
SharedVariables.cpp
QString ShareVariables::getTextoPesquisa()
{
return TextoPesquisa;
}
void ShareVariables::setTextoPesquisa(QString TxtPesquisa)
{
TextoPesquisa = TxtPesquisa;
}
bool ShareVariables::getLoginUtilizador()
{
return LoginEfectuado;
}
void ShareVariables::setLoginUtilizador(bool UtilizadorComLogin)
{
LoginEfectuado = UtilizadorComLogin;
}
Then to have access to the functions in my 2 (or more) cpp's, I use this :
File1.cpp (the one who writes)
SharedVariables e1;
e1.setTextoPesquisa("StringHERE");
File1.cpp (the one who reads)
SharedVariables e2;
qDebug() << e2.getTextoPesquisa();
The problem is that when the e2 is initialized my QString TextoPesquisa becomes empty again, And i don't know who to solve this problem, since I want that the values stay the same so I can access everywhere with this functions.
The variable need to be static:
class SharedVariables
{
private:
static QString TextoPesquisa;
Also make sure you declare TexttoPesquisa in cpp file:
QString SharedVariables::TextoPesquisa;
Because static variables aren't bound to particular class instance, they need their own memory location.
e2 is empty because you are using two different instances of the same class.
You need to create a SharedVariables object (on your main for example) and then use it on your various classes in .cpp files.