I have a problem where I can't seem to get a output to display in a console when doing it through a function.
It works when doing it through Main(), but just blank when doing it through the function.
Below is some of my code:
#include "ConferencePaper.h"
#include "JournalArticle.h"
#include "Reference.h"
#include <QDebug>
#include <QTextStream>
QTextStream cout(stdout);
int main()
{
//QApplication app(argc, argv);
QStringList list1;
list1 << "This is a test";
Reference a("Marius",list1,1,"c"); //Instance of the Reference class created with parameter values
cout << "Title: " << a.getTitle(); //This works fine
a.toString();
return 0;
}
//Reference Function
#include <QString>
#include <QStringList>
#include <QTextStream>
#include "Reference.h"
Reference::Reference(QString ti, QStringList as, int ye, QString id): title(ti), authors(as), year(ye), refID(id){}
QString Reference::toString()
{
return QString("Title: %1\n") .arg(getTitle()); //Does not display anything
}
In your toString() method:
QString Reference::toString() {
return QString("Title: %1\n") .arg(getTitle()); //Does not display anything
}
there is nothing which could cause to print anything on the console. You are simply returning the string as a result of that method.
To display something, you need to output the string which is returned from the method, e.g. in your main() function like
cout << a.toString().toUtf8().constData();
or
cout << a.toString().toLocal8Bit().constData();
Note that you need to convert your QString to a data type for which a << operator is available for ostream. See also How to convert QString to std::string?
As mentioned above several times, X.toString(); would just return QString to a caller, then depending on what you're trying to achieve you may:
print it to console using cout << ...
print it to Application Output pane in your Qt Creator using qDebug() << ...
(see QDebug Class reference for details, it's pretty common debugging technique)
Related
I am trying to create an Application that lets the user input an integer value and then sends it via tcp to my esp32.
I have set up my esp32 as a tcp server which connects to my wifi router and than shows its ipv4 adress via serial Monitor. The esp32 is connected to 2 stepperdriver and shall later control them with the data from the Application.
So my Application is working when the data that has to be sent is known before runtime for example i could create a const char* variable with the desired data and then simply send it with socket->write(foo);.
But thats not working for me because i need to get input from the console at runtime and then pass it to the function socket->write(). The problem there is that the QTcpSocket Object has to be in another thread. So i am stuck at figuring out how to pass data in between threads.
I tried to use the signal and slot mechanism to do so which if i correctly understood is meant to be used for that.
Especially this line gives me a huge headache. (the line is in the main function)
emit IO->doSendData(IO->getInput());
I try to emit the signal doSendData and pass the input from the console to the connected slot sendData() which is a method from the network class which object is in the threadNET and the object thats getting the input from the console lives in the main thread i guess thats the problem here but i have no glue how to fix it.
I dont get any error messages in QTcreator.
Thanks in advance for taking your time to help me.
If something is unclear feel free to ask me anything. Thats my first post on Stack overflow and i would appreciate any feedback on how to increase the quality of my question.
Complete code
main.cpp
//MAIN
#include <QCoreApplication>
#include <network.h>
#include <userio.h>
#include <QThread>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QThread* threadNET = new QThread();
network* net = new network();
userIO* IO = new userIO();
net->moveToThread(threadNET);
QObject::connect(threadNET,
&QThread::started,
net,
&network::Connect);
QObject::connect(IO,
&userIO::doSendData,
net,
&network::sendData);
threadNET->start();
while(true)
{
emit IO->doSendData(IO->getInput());
}
return a.exec();
}
network.h
//NETWORK HEADER
#ifndef NETWORK_H
#define NETWORK_H
#include <QObject>
#include <QTcpSocket>
#include <QAbstractSocket>
#include <QString>
#include <QDebug>
#include <iostream>
#include <string>
class network : public QObject
{
Q_OBJECT
public:
explicit network(QObject *parent = nullptr);
~network();
signals:
void finished(QString ffs);
void error(QString err);
public slots:
void Connect();
void sendData(QString dataToSend);
private:
QTcpSocket *socket;
};
#endif // NETWORK_H
userIO.h
//USERIO HEADER
#ifndef USERIO_H
#define USERIO_H
#include <QObject>
#include <QString>
#include <iostream>
#include <QDebug>
#include <limits>
#include <string>
class userIO : public QObject
{
Q_OBJECT
public:
explicit userIO(QObject *parent = nullptr);
QString getInput();
signals:
void doSendData(QString dataToSend);
public slots:
};
#endif // USERIO_H
network.cpp
//NETWORK SOURCE
#include "network.h"
network::network(QObject *parent) : QObject(parent)
{
}
network::~network()
{
}
void network::Connect()
{
socket = new QTcpSocket(this);
socket->connectToHost("192.168.179.167", 80);
if(socket->waitForConnected(5000))
{
std::cout << "Connected to TcpServer";
}
else
{
qDebug() << "Error: " << socket->errorString();
}
emit finished("send help");
}
void network::sendData(QString dataToSend)
{
qDebug() << "sendData" << dataToSend << "\n";
std::string convert = dataToSend.toStdString();
const char* formattedData = convert.c_str();
socket->write(formattedData);
}
userIO.cpp
//USERIO SOURCE
#include "userio.h"
userIO::userIO(QObject *parent) : QObject(parent)
{
}
QString userIO::getInput()
{
std::string rawInput;
qDebug() << "Enter the amount of steps to go\n";
std::cin >> rawInput;
while(std::cin.fail())
{
qDebug() << "Invalid input only Integer numbers are allowed\n";
qDebug() << "try again...\n";
std::cin.clear();
std::cin.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
std::cin >> rawInput;
}
QString convert;
convert.fromStdString(rawInput);
return convert;
}
QString::fromStdString(const std::string &str)
is a static member that returns a copy of the str string.
calling convert.fromStdString(rawInput); does not store copied string in convert !!
you need to write :
convert = QString::fromStdString(rawInput)
OR
direct initialization:
...
QString convert(QString::fromStdString(rawInput));
return convert;
Up until now, I output everything using qDebug().noquote(). This is easy because it just requires a simple #import <QDebug>
Now I need everything to output to stdout, but I don't know how to do it easily. This how I was taught:
QTextStream cout(stdout, QIODevice::WriteOnly);
However, creating a new object is a tad bit more cumbersome than a simple #import <QDebug>. What is the good/least cumbersome way to handle stdout in qt?
qDebug(), qInfo(), etc. are all piped to a default message handler. But you can easily install your own that writes the debug strings to a different stream, file, or anything. All you need to do is define a message handler function and install it using qInstallMessageHandler().
Putting it all together, here's a complete example:
#include <QDebug>
void myMessageOutput(QtMsgType type, const QMessageLogContext &context, const QString &msg)
{
QTextStream cout(stdout, QIODevice::WriteOnly);
cout << msg << endl;
}
int main(int argc, char *argv[])
{
qInstallMessageHandler(myMessageOutput);
qDebug().noquote() << "Hello world!";
}
The best way is the one you mentioned. You don't have to create a new local variable:
QTextStream(stdout) << "Hello world!" << endl;
If the source text is not Latin-1 encoded then you need to convert to QString before passing it to the stream operator:
QTextStream(stdout) << QString::fromUtf8("utf8 literal") << endl;
i am using the library Gtkmm with c++ but i have a problem to display the value of an entry. This is my code :
#include <gtkmm/box.h>
#include <gtkmm/button.h>
#include <gtkmm/main.h>
#include <gtkmm/window.h>
#include <gtkmm/entry.h>
#include <iostream>
int main(int argc, char* argv[]) {
Gtk::Main app(argc, argv);
Gtk::Window fenetre;
Gtk::VBox *boiteV = Gtk::manage(new Gtk::VBox(false, 10));
Gtk::Entry *param = Gtk::manage(new Gtk::Entry());
boiteV->pack_start(*param);
Gtk::Button *bouton = Gtk::manage(new Gtk::Button("Tester !"));
boiteV->pack_start(*bouton);
fenetre.add(*boiteV);
std::string a = param->get_text();
bouton->signal_clicked().connect([&a]() {std::cout << a << std::endl;});
fenetre.show_all();
Gtk::Main::run(fenetre);
return EXIT_SUCCESS;
}
My problem is when i click on the button i have nothing whereas i wrote a value in the entry. Thank you a lot for your help !
The problem is that you take the string a after creation of the button and capture that string (which is empty) in the lambda function. When you press the button, the text is not queried again, but the value of the string a, which never changed, is printed.
You can instead capture the pointer to the button itself (by value!) and call get_text() every time like this:
bouton->signal_clicked().connect(
[param]() {
std::cout << param->get_text() << std::endl;
}
);
I am trying to implement GUI for a simple C++ using Qt to understand how it works. The C++ program and the GUI are in seperate projects in the same solution in VS 2015. The Qt program will call the C++ program using QProcess' start() function. The C++ console application will be running the background will the Qt program acts as an interface. My question is, how I do I pass values to the C++ program using QProcess and How do I obtain the output from the C++ program? Here is the sample program I am working with:-
The C++ Program
#include<iostream>
#include<fstream>
using namespace std;
void main() {
int a;
cout << "Enter a number" << endl;
cin >> a;
cout << "The Square of the number is " << (a*a) << endl;
ofstream write;
write.open("test.txt");
write << (a * a);
write.close();
}
The Qt Program
#include "FrontEnd.h"
#include <QtWidgets/QApplication>
#include <qprocess.h>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FrontEnd w;
w.show();
QProcess p1;
p1.start("Interface.exe");
p1.write("5",5);
return a.exec();
}
I tried to pass the value using the write() function but it did not seem to work as the test.txt file remained empty. The Qt program I have written lacks the GUI features as I will be adding them once I figure out how to send and recieve data using QProcess. Thank you for your assistance!
You have many problems in the code you are showing:
You are passing write two arguments "5" and 5, this means that it will use 5 chars from the the char* "5". Absolutely, this is not what you want as this will lead to undefined behavior resulted from accessing memory that does not belong to your data.
Instead you should be using the second version of write which accepts a zero-terminated string, like this: p1.write("5");
In order to make cin in your console program know that the number it should read is finished, you should pass a new line after your number, so your call will end up like this: p1.write("5\n");
You should use the readyRead signal in the Qt program to get notified when your process has new output that you can read, and then you may call readAll from a slot which is connected to that signal.
For completeness, Here is how your code should be:
interface.cpp
#include<iostream>
using namespace std;
void main() {
int a;
cin >> a;
//No need to use file output
//it is simpler and more appropriate to read the output from stdout
cout << "The Square of the number is " << (a*a) << endl;
}
The Qt program
#include <QApplication>
#include <QWidget>
#include <QProcess>
#include <QDebug>
#include "FrontEnd.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
FrontEnd w;
w.show();
QProcess p1;
p1.start("Interface.exe");
p1.write("5\n");
QObject::connect(&p1, &QProcess::readyRead, [&p1](){
//output to qDebug, you may want to update some GUI component instead
qDebug() << p1.readAll();
});
return a.exec();
}
I wrote a program to output a random quote from a QStringList to a console window, program runs but I can't figure out why nothing appears in the window. Please help
here is the code:
#ifndef RANDOMADVICE_H
#define RANDOMADVICE_H
#include <QString>
#include <QStringList>
class randomAdvice
{
public:
randomAdvice();
QString returnAdvice();
private:
QStringList randomList;
QString output;
};
#endif // RANDOMADVICE_H
here is the cpp file randomadvice.cpp
#include "randomadvice.h"
#include "cstdlib"
#include "ctime"
#include <QString>
randomAdvice::randomAdvice()
{
randomList = QStringList()
<< "In order to succeed, your desire for success should be greater than your fear of failure. - Bill Cosby"
<< "Always be yourself, express yourself, have faith in yourself, do not go out and look for a successful personality and duplicate it. - Bruce Lee"
<< "A successful man is one who can lay a firm foundation with the bricks others have thrown at him. - David Brinkley"
<< "Strive not to be a success, but rather to be of value. - Albert Einstein"
<< "To succeed in life you need 2 things: Ignorance and confidence. - Mark Twain"
<< "Success is a lousy teacher. It seduces smart people into thinking they can't lose. - Bill Gates"
<< "Remembering that you are going to die is the best way I know to avoid the trap of thinking that you have something to lose. You are already naked. There is no reason not to follow your heart. - Steve Jobs";
}
QString randomAdvice::returnAdvice()
{
srand(time(NULL));
output = randomList.at(rand() % randomList.size());
return output;
}
and the main file:
#include "randomadvice.h"
#include <QtCore/QCoreApplication>
#include <QTextStream>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QTextStream out(stdout);
randomAdvice ra;
QString adviceString = ra.returnAdvice();
out << adviceString;
return a.exec();
}
QTextStream buffer the output until it is flushed or a newline is written.
You can either add out.flush() after out << adviceString or change out << adviceString to out << adviceString << endl.
Try QTextStream out(stdout, QIODevice::WriteOnly);