QSettings of ini file from internet - qt

Im using this function so far:
bool MSSQL::checkSettings()
{
QString settingsFile = "someDir/setup.ini";
QString fileName(settingsFile);
QFile file(fileName);
if(QFileInfo::exists(fileName)) {
return true;
}
else {
qDebug() << "Error: No INI File Found on path:" << settingsFile;
return false;
}
}
which works fine.
However when I wish to use an online ini file which is reachable (because can be opened via browser link), then its a false, for example if i use:
QString settingsFile = "http://localhost/something/setup.ini";
which QT should be able to read, then it doesnt work...
any ideas?

I dont see where you are using QSettings at all. You are using QFile, which is representation of a local file.
To your question:
QSettings does not able to read/write setting from URL. You have to download it manually before instantiating QSettings, See QNetworkAccessManager.
Or you may try to make your own settings provider, by using: QSettings::registerFormat() static function.

Related

Qt5.12.0 relative path doesn't work but absolute path works

I'm using Qt5.12.0 on macOS Catalina 10.15.6.
I can load files using absolute path, but can't do that using relative path. However, I want to use the relative path to robust the code. I think the absolute path is not maintainable as relative path.
I have tried QDir::currentPath();, QApplication::applicationDirPath(), and QCoreApplication::applicationDirPath(); but they all give me the absolute path.
Below are loadPhotos, so far, only the print dir.entryList(QDir::Files) part is used.
// load photo cantainer
void TimerDialog::loadPhotos(const QString &path)
{
qDebug() << "in func loadPhotos, path is: " << path;
// in func loadPhotos, path is: "./images"
// QDir dir("");
QDir dir(path);
// trevase current directory
QStringList fileList = dir.entryList(QDir::Files);
qDebug() << "in func loadPhotos, fileList is: " << fileList;
// TODO in func loadPhotos, fileList is: ()
for (int i=0; i<fileList.size();i++) {
QImage image(path+"/"+fileList.at(i));
qDebug() << "fileList.at(i): " << fileList.at(i);
m_vecPhotos << image;
}
QStringList folderList = dir.entryList(QDir::Dirs|
QDir::NoDotAndDotDot);
for (int i = 0; i < folderList.size(); ++i) {
loadPhotos(path+"/"+folderList.at(i));
}
}
I put images folder under the project file, which is bili_tedu_timer. There are 20 pictures in the images folder.
I have disabled Shadow build in Projects mode
I tried qmake in Qt creator, but it still doesn't work #ניר
It is truth that if the absolute path works, the relative path will work. The question is, where is the current directory?
I've implemented three kinds of ways to see where the current directory is. But I am unaware that the current directory is MacOS, which is not project directory bili_tedu_timer, where I put images folder.
From the current Path output,bili_tedu_timer is THREE level upper than MacOS, so use ../../../ to get to the correct folder.
Actually, it's quite straightforward. But as a beginner as me, I don't have the sensitive about the program. What I did was I save a file (Thx to my roommate, she told me this method) to find out where I am, reference. Without surprise, I am in MacOS. I suddenly realized that I was so close to the solution.

I can't quit properly my apps if I use mysql connection

If I do not use connection I can properly exit.
In Pdv.h file
namespace Pdv {
...
extern QSqlDatabase db;
...
}
In LoginDialog.cpp file
QSqlDatabase Pdv::db;
...
Pdv::db= QSqlDatabase::addDatabase("QMYSQL3");
Pdv::db.setHostName(Pdv::DB_URL);
Pdv::db.setUserName(Pdv::DB_USER);
Pdv::db.setPassword(Pdv::DB_PASS);
Pdv::db.setDatabaseName(Pdv::DB_DB);
if(!Pdv::db.open()) {
...
// Checking user login/password and retrieve many variables
...
In mainwindow.cpp file
...
void MainWindow::closeEvent(QCloseEvent *event) {
...
if(Pdv::db.isOpen()) {
qDebug() << "Opened 1";
Pdv::db.close();
qDebug() << Pdv::db.lastError();
if(Pdv::db.isOpen())
qDebug() << "Opened 2";
}
Pdv::app->quit(); // or QApplication::quit();
}
I got this error in QTCreator console
Opened 1
QSqlError("", "", "")
Le programme s'est terminé subitement.
/home/cosmic/src/build-Pdv-Desktop-Debug/Pdv crashed.
A idea?
To make proper exit with usage of QSqlDatabase, you need preferably:
remove all instances of QSqlDatabase objects (because as you copy them, they will keep connection open).
As second condition, you need to use QSqlDatabe::removeDatabase() call. (also this call will make qDebug message if database is still in use occasionally - some QSqlDatabase object is left somewhere - it will help to identify a problem).
If you close and delete your MainWindow, and your program then crashes, then other parts of the program must be trying to use the MainWindow pointer even though it is destroyed.
I think the problem is the line of code Pdv::app->quit(); Try with QApplication::quit(); instead or review the code in Pdv::app->quit();.

Writing to file in Qt

I have a problem with writing to file, the problem is :
If I write the directory ":/Files/Scores.txt" it won't write anything but it reads from same directory.
But if I used this directory "D:/TicTacToe/TicTacToe/Scores.txt" it writes and reads but i will give the game to my instructor and the path won't be same and the file won't open, any ideas ?!
My write code:
void Write ( QString file)
{
QFile sfile(file);
if(!sfile.open(QFile::ReadOnly |QFile::Text))
{
return;
}
QTextStream in(&sfile);
QString lscores =sfile.readAll() ;
sfile.close();
if(!sfile.open(QFile::WriteOnly |QFile::Text))
{
return;
}
lscores=" "+Xscore+"\t"+" "+Oscore+"\n"+lscores;
QTextStream out(&sfile);
out <<lscores;
sfile.close();
}
Resource files (the ones you put in .qrc file) are read only, as MrEricSir mentioned. If you want to have some configuration/score file with your app you can for example use QApplication::applicationDirPath()
QString settingsFile = QApplication::applicationDirPath() % QLatin1Literal("/scores.txt");
This way you will have always absolute path to the file inside your app directory.
You can also use QDesktopServices::storageLocation with QDesktopServices::DataLocation parameter to obtain data location for your application.

Qt5 - How to make qurl detect wether the given url is local or not and add "http://" if not?

QUrl class can be used to open both local or online file. I used QLineEdit to take URL as QString and give it to QUrl. The program can access both local and online file. My point question is: is there any official way to automatically detect if the given url is local or online and add http:// automatically if the url is online?
For example, if user type www.google.com, it should be online and should be added http:// before it being processed. If user type /home/username/somepath it should be offline.
Of course a little if and else thing with string pattern check can be used for this purpose. My question is, if there's officially supported way to do something like this from Qt5.
You can use QUrl:fromUserInput(...) for that purpose.
QString first("qt-project.org");
QString second("ftp.qt-project.org");
QString third("hostname");
QString fourth("/home/user/test.html");
qDebug() << QUrl::fromUserInput(first); // QUrl( "http://qt-project.org" )
qDebug() << QUrl::fromUserInput(second); // QUrl( "ftp://ftp.qt-project.org" )
qDebug() << QUrl::fromUserInput(third); // QUrl( "http://hostname" )
qDebug() << QUrl::fromUserInput(fourth); // QUrl( "file:///home/user/test.html" )

Using QNetworkAccessManager across dll

I have a Qt5 application which uses QNetworkAccessManager for network requests which is accessible via a singleton and QPluginLoader to load extensions which add the functionality to the program. Currently I'm using static linking for plugins and everything works just fine.
However I want to switch to using dynamic libraries to separate the core functionality from other parts of the app. I've added the necessary declspec's via macro, and made necessary adjustments in my .pro files.
The problem is that very often (like, 3 of 4 starts) QNetworkAccessManager when used from dlls just returns an empty request or a null pointer. No data, no error string, no headers.
This is the code I'm using for loading plugins:
template <typename PluginType>
static QList<PluginType*> loadModules() {
QList<PluginType*> loadedModules;
foreach (QObject* instance, QPluginLoader::staticInstances()) {
PluginType* plugin = qobject_cast<PluginType*>(instance);
if (plugin) {
loadedModules << plugin;
}
}
QDir modulesDir(qApp->applicationDirPath() + "/modules");
foreach (QString fileName, modulesDir.entryList(QDir::Files)) {
QPluginLoader loader(modulesDir.absoluteFilePath(fileName));
QObject *instance = loader.instance();
PluginType* plugin = qobject_cast<PluginType*>(instance);
if (plugin) {
loadedModules << plugin;
}
}
return loadedModules;
}
Which is used in this non-static non-template overload called during the startup:
bool AppController::loadModules() {
m_window = new AppWindow();
/* some unimportant connection and splashscreen updating */
QList <ModuleInterface*> loadedModules = loadModules<ModuleInterface>();
foreach (ModuleInterface* module, loadedModules) {
m_splash->showMessage(tr("Initializing module: %1").arg(module->getModuleName()),
Qt::AlignBottom | Qt::AlignRight, Qt::white);
module->preinit();
QApplication::processEvents();
// [1]
ControllerInterface *controller = module->getMainController();
m_window->addModule(module->getModuleName(),
QIcon(module->getIconPath()),
controller->primaryWidget(),
controller->settingsWidget());
m_moduleControllers << controller;
}
m_window->addGeneralSettings((new GeneralSettingsController(m_window))->settingsWidget());
m_window->enableSettings();
/* restoring window geometry & showing it */
return true;
}
However, if I insert QThread::sleep(1); into the line marked 1, it works okay, but the loading slows down and I highly doubt it is a stable solution that will work everywhere.
Also, the site I'm sending requests to is MyAnimeList.
All right, now I have finally debugged it. Turned out I deleted internal QNetworkAccessManager in one of the classes that needed unsync access. That, and updating to Qt5.3 seem to have solved my problem.

Resources