I'm trying to use QHttp for an update app. But there is a problem for me which I can't solve.
I try to download a file (works perfectly) but if there is no connection to the internet, the file is created but has 0 bytes. My old file is then overwritten with the empty file, which is not so good for the application trying to use the file. What I need is to check if the computer is connected to the internet.
Note: proxy may set. I used this example from Qt's homepage.
You should switch to the QNetworkAccessManager as Mike Suggested, here is an example of a slot on the finished() signal:
void ApplicationUpdate::replyFinishedhttpGetChangeLog(QNetworkReply* myReply) {
if (myReply->error() != QNetworkReply::NoError)
{
QByteArray returnedData = myReply->readAll();
if (returnedData.size() > 0) {
if( m_fileChangeLog->exists() )
{
m_fileChangeLog->close();
m_fileChangeLog->remove();
}
m_fileChangeLog->open(QIODevice::ReadWrite);
QDataStream out( m_fileChangeLog );
out.writeRawData(returnedData.data(), returnedData.size());
m_fileChangeLog->flush();
m_fileChangeLog->close();
}
}
}
Firstly, you should probably now be using QNetworkAccessManager rather than QHttp.
Using either of them, you should do a dummy query to a site you pretty much always know will be up (e.g. http://www.google.com/) and use that as a test to see if you have an internet connection.
A better way of doing this would be instead to use QNetworkAccessManager to read into a QByteArray and then check it isn't empty before writing to your file.
Whenever you write a file that might already exist, you should create a QTemporaryFile first, then, after successful download, rename it to the final name.
i ran into the same problem, after a bit of poking around, I've isolated the problem down to the project configuration file (.pro), in the broken configuration I was linking the networking library explicitly with the statement : "LIBS += -lQtNetwork". In the working configuration, I used the more formal (and qt compilant) approach of delcaring what Qt components are included in the project, like so: "QT = core gui network xml", adjust accordingly for your sitiation, the netowkring slots did not work on windows when explicitly linked but did work on linux. Using the qt compilant approach works on both platforms.
Related
I am trying to securely clear out a directory using SDelete. I know that this is used from the Command line, but how I would I go about automatically clearing the directory from my C++ code, also using Qt if this has a built any built in functions. I could not find anything with searching and this is my first time doing something like this. Any help would be greatly appreciated, thanks.
It is good that you're not trying to re-create the functionality of SDelete. It would be a LOT of work to do as good as a job as what SDelete does. Invoking the existing application is a wise choice.
Now, on to your question... If you want to use QT, then what you need is something like this:
QString path = QString("sdelete", QStringList() << "Bogus.txt");
QProcess sdelete;
sdelete.start( path );
sdelete.waitForFinished();
That will start the process sdelete with the parameter Bogus.txt and then wait until the application is finished.
More Info: https://doc.qt.io/archives/qt-4.8/qprocess.html#start
Edit from OP : I found that using the following worked for me with the argument being passed in being a QString.
QProcess::execute("sdelete -s path");
I am getting started with Unreal Engine 4. I come from Libgdx and I am familiarized using WebSockets clients in my games and NodeJS with 'ws' on the server.
How ever, I can't find information about Websockets and Unreal Engine 4.
I know that given that it is programmed with C++ you can add external static libraries to the unreal project.
Can I use this c++ websocket library?
https://github.com/zaphoyd/websocketpp
Will it run on Windows, Mac and console?
I am not an expert of c++ and static libraries.
Please help, thanks!
You can follow this tutorial on TCP Sockets.
You will need to make some changes on the code, as it doesn't run on UE 4.10 (the tutorial is originally from 2014).
On the .h file define 2 timer handles:
FTimerHandle TimerHandle_Connection;
FTimerHandle TimerHandle_Socket;
On the .cpp file, inside StartTCPReceiver(...) change the line where the timer is set to:
GetWorldTimerManager().SetTimer(TimerHandle_Connection, this, &AYourClass::TCPConnectionListener, 0.01, true);
and on TCPConnectionListener(...) change the line where the timer is set to:
GetWorldTimerManager().ClearTimer(TimerHandle_Connection);//optional, only if you want to stop listening for new connections
GetWorldTimerManager().SetTimer(TimerHandle_Socket, this, &AYourClass::TCPSocketListener, 0.01, true);
(Another option would be to thread these functions instead of having them in timers)
Just in case, if you are new to UE, don't add the code directly on the IDE. Go to the Content Browser > Add New > New C++ Class. You can create a new class that inherits from Actor, and when you want to start to listen to connections, you spawn that Actor.
You can use any websocket or third party asset with unreal engine. You can simply add the headers in your Build.cs file using PrivateIncludePathModuleNames for example (there's also a public include path) and it takes an array of strings where each string is a folder essentially. If you want to add a library (lib) file you can just add it like this:
if (Target.Platform == UnrealTargetPlatform.Win32 ||
Target.Platform == UnrealTargetPlatform.Win64)
{
PublicSystemLibraries.Add("crypt32.lib");
}
You can also add full paths here. If you want to do a delayed load you can just use PublicDelayLoadedDlls.Add("name") <- I may have the syntax wrong on this one but it's easy to google it.
Aloha,
Im developing a small "ServerManager" for myself using QT (C++).
Anything worked till this point:
I use QSettings to store all relevant Settings (like Server, installed Plugins and so on).
As I didn't want to instanciate the QSettings class everywhere I have to use it, i thought i could try to instanciate it one time in the main.cpp and make it available using the qApp->setProperty() method.
How i setup the QSettings class:
QSettings* Settings = new QSettings(".\\Settings.ini", QSettings::IniFormat);
How i "publish" it:
qApp->setProperty("Settings", QVariant::fromValue<QSettings*>(Settings));
And finally. If i use it like this:
QSettings* Settings = qApp->property("Settings").value<QSettings*>();
Settings->beginGroup("Servers");
The whole application crashed with an SIGSEGV signal (Segmentation fault).
Stacktrace: Stacktrace http://host-it.tk/Upload/53ab11da0d706/37.PNG
I really got no clue why this happens.
Maybe the solution is obvious, but this is my "first real" Application.
It seems like I got the well known "tunnel view".
Thanks for your time!
Relevant code parts: http://pastebin.com/VzZ9uuJi
QT-Version: 5.2.1
Since a QSettings* is not a usual QVariant type, you would have to declare it.
Q_DECLARE_METATYPE(QSettings*);
This is not the usual way to share QSettings, though. Since it is in INI format, consider just passing the location to the INI file with absolute paths instead:
QFileInfo path(".\\Settings.ini");
qApp->setProperty("SettingsLocation", path.absoluteFilePath());
Then later:
QSettings Settings(qApp->property("SettingsLocation").toString(), QSettings::IniFormat);
Settings.beginGroup("Servers");
So as of Qt 5, QHttp is deprecated and we're all supposed to use QNetworkAccessManager now. Fine. But how do I make a request (HTTP or otherwise) from my multihomed machine without feeling like I'm playing roulette?
If there is no way, then what is a workaround? For my specific case right now, I just need to download a file via HTTP. But is there really no way to do this in a generic way with QtNetwork?
The quick workaround would be to use this in your project file
QT += http
It is still available in a separate module for compatibility.
If you are lucky enough that the desired interface is a separate physical (hardware) interface, you can do e.g. (web_view is a QWebView*):
QNetworkConfigurationManager config_manager;
QList<QNetworkConfiguration> configs = config_manager.allConfigurations();
bool found_interface = false;
QString desired_interface_name("eth1");
foreach (const QNetworkConfiguration &config, configs) {
if (config.name() == desired_interface_name) {
found_interface = true;
QNetworkAccessManager *network_access_manager = new QNetworkAccessManager;
network_access_manager->setConfiguration(config);
web_view->page()->setNetworkAccessManager(network_access_manager);
break;
}
}
if (!found_interface) {
//we failed to find the interface!
}
Again, this will not work if the IP is bound to a virtual interface part of one physical interface (e.g. eth1:1, eth1:2, etc). I am still looking for a solution for that case.
I'm an unfortunate beginner at C++ and using the Qt GUI designer program seemed perfect for my needs, except I'm having problems trying to write out the code necessary for this. I could use the QSettings string to store local settings on the hard drive, but I personally hate it when programs do the %HOME_LOCAL%\APPS_SETTINGS bull that some do. I need to save a text file for both settings and a local\host database, within the program directory, to remember strings to read from later.
What is the line of code I need to make use of a local host text database or is there a better option? And how can I store that with the local program inside its directory?
You can use QSettings with any file, with constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 ).
To get the program directory, you can use QCoreApplication::applicationDirPath().
So, answer to your question, statement to put after creation of QApplication instance:
QSettings *settings = new QSettings(
QCoreApplication::applicationDirPath() + "/settings.ini",
QSettings::IniFormat,
qApp);
But, as noted in the comments under question, if you're making your program for general distribution, you should use the OS default. Examine all the constructors of QSettings to see what it can do. User does not often have write permission in the application directory. Note that you can also store settings to Windows registry with QSettings::NativeFormat.