QFileDialog freezes on close/destructor (with selected file or cancel) - c++

I'm developing applications in qt with Ubuntu 15.04 and the respective qt pakage 5.4. For some reason, out of nowhere the application would freeze after selecting a file within a QFileDialog (or even cancelling).
I found some similar topics on the web but most were concerned with a now resolved bug in qt 5.1 and (non-)native QFileDialogs.
Then I found out this is related to more than just my own application - even qtcreator would freeze on leaving the QFileDialog, now.
There seems to be a deadlock in the destructor of QFileDialog.

The following snippet is from qsettings.cpp (line 1382), within void QConfFileSettingsPrivate::syncConfFile(int confFileNo)
QLockFile lockFile(confFile->name + QLatin1String(".lock"));
if (!readOnly) {
if (!confFile->isWritable() || !lockFile.lock() ) {
setStatus(QSettings::AccessError);
return;
}
}
It turns out some other qt application has left a lock file which causes all other applications' QFileDialog destructor to be deadlocked within the above lock call.
I searched for .lock files in my home folder and after deleting
./.config/QtProject.conf.lock and a second file similar to .config/USERNAME/APPTARGETNAME.conf.lock
the QFileDialog works well, agian.
I just now can't reproduce which of the two files did cause the deadlock.
Hope this helps anyone in a similar situation!

Related

Qt deployed (macdeployqt) application does not create a file

I'm facing the following problem:
I wrote a simple application to track working hours. Therefor I create a *.db file programmatically.
Launching the application from Qt Creator (debug or release) works perfectly fine.
I used the macdeployqt tool to get a *.dmg file. When starting the application now the method (see below) cannot open, respectively create the *.db file and I run out of ideas why. In addition to this, the application should output some *.csv files. This also fails.
One more information, running the application as administrator using the sudo command on terminal...well it works and the *.db file and *.csv files get created.
So I am quite sure it must deal with file permissions but I have no idea how to change this except for changing it in the information context menu but this didn't help at all.
Below the method for the *.db file which always returns false when not launching the app from Qt Creator:
QFile file(Globals::Environment::WORKING_DIRECTORY + "/" + "Records.db");
if(file.open(QIODevice::ReadWrite))
return true;
else
{
QMessageBox msg;
msg.setWindowTitle("Error");
msg.setText("Failed to create database file!");
msg.exec();
}
return false;
I am on MacOS 10.11.3.
Qt 5.5.1 (Clang 6.1 (Apple), 64 bit)
If more information is needed, I will provide it of course.
Thanks a lot for every help in advance.

Qt5: Preventing another instance of the application doesn't work anymore...!

I am using Qt5 on a Windows7 platform.
My application is some kind of TCP server listening on port 8002, so I only want one instance of it.
In order to prevent multiple instances of my application, I use(d) the code below (found here on StackOverflow):
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QSharedMemory sharedMemory;
sharedMemory.setKey("TcpServer-Key");
if(sharedMemory.create(1) == false)
{
QMessageBox::warning(NULL, "Warning!", "Another instance already running!");
a.exit(); // exit already a process running
return 0;
}
...
Well, the code above used to work just fine, until I upgraded my Qt to 5.5.1.
Now, with Qt 5.5.1, I don't see the warning message-box anymore!... When I try to start another instance, the running app disappears/stops and a new app is started!!!
Please help, what should I do? But don't tell me to switch back to Qt 5.4.x :(
Remark: I forgot to mention that I set & used msvc2012 compiler during tests (not minGW, as I wasn't able to build log4cxx for it).
UPDATE: Could it be an issue related to the antivirus installed on that PC (at the office, i.e. McAfee)?... Now I'm at home (AVG antivirus and MinGW compiler and log4cxx removed) and I am unable to reproduce the above described issue :(
I finally discovered where the problem was... and it's not the antivirus to be blamed :)
When I upgraded the Qt (Creator v3.6.0) to the newest version (5.5.1), there is a setting in Tools->Options->Build&Run named [Stop app before building]... that was set to Current project or something. Hence, the Qt Creator was killing the old instance before launching a new one(!).
Setting this option to None solved the issue.
So, it seems the code was just fine, antivirus was fine, yet launching the app from within Qt Creator was somehow restricted to only one instance :)
I decided to share this, maybe it will be helpful for other folks as well.
Remark : I checked again and now I can confirm: That setting didn't exist before, at least not in Qt Creator v3.3.2.

Solved but not explained: Qt5.5 webkitwidgets, missing DLL, unexpected crash

I made a very simple and boring postal code -> city lookup program (it uses an online api).
I wanted to add functionality which allows to select any country (which the api can process). For this I wanted to load the main page and parse the DOM to get all the countries. This requires webkitwidgets. http://www.zippopotam.us/#where (this is the table I want to extract the information from)
Unfortunately, when attempting to run the program it never even starts and gives me the Application Output:
Starting ZipcodeToLocation.exe...
The program has unexpectedly finished.
ZipcodeToLocation.exe crashed
So I try running the debugger:
An exception was triggered:
Exception at 0x77cbd4f2, code: 0xc0000135: DLL not found, flags=0x0.
During startup program exited with code 0xc0000135.
Weird... so I try finding this error message on the internet and nothing really helps me. I think maybe I set something up wrong, so I open the webkitwidgets examples and compile those. When attempting to run - same error.
Using programs like some dependency walker didn't really help me much either.
I ran the MaintananceTool to check whether I was missing something, but I wasn't able to detect anything.
Im running QtCreator on Windows btw.
My .pro
QT += core gui webkitwidgets network
CONFIG += c++14
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = ZipcodeToLocation
TEMPLATE = app
SOURCES += main.cpp\
MainWindow.cpp
HEADERS += MainWindow.hpp
FORMS += MainWindow.ui
If I remove the following portion from my main window ctor, everything runs es expected:
auto page = new QWebPage(this);
page->mainFrame()->load(QUrl("http://www.zippopotam.us"));
Note: this is currently the only section using webkitwidgets.
I would be really happy if someone could help me overcome this roadblock and has any suggestions on what might be going wrong.
Edit: Just to make it complete, a screenshot of the depends run: https://i.imgur.com/YWpdlO6.png?1
The german part translates to "The System can't find specified file".
Edit2: If you have QtCreator installed and want to attempt reproducing my error, create new QWidgets application, edit your .pro like so:
QT += core gui webkitwidgets
and this line at the end of MainWindow ctor (probably any usage of webkitwidgets would do):
#include <QWebKitWidgets>
//...
QWebPage *page = new QWebPage(this);
Edit3: As a reaction to a recent comment, I tried copying all dlls from the Qt directory to the .exe location (release) and tried running it from there. It said "Missing Qt5Positioning.dll". Which is weird, because I am not using the location module... But I guess that explains the missing dll crash?
Edit4:
I finally had enough and simply completely reinstalled Qt from scratch. Somehow my installation had to be messed up, because after that the problem vanished.

Qt Creator - Code is running but I get an error message from the IDE

As soon as I run my code (note that I'm using C only, no QT and no C++) I get the following message from the application output inside the IDE:
Cannot obtain a handle to the inferior: The parameter is incorrect.
When I delete the makefiles and debug/release folders it's running but after some time I still get the error. It's not that much of a problem though, the code runs and everything is fine but this error pops up and it's quite annoying.
The content of the .pro file is:
TEMPLATE = app
CONFIG += console
CONFIG -= app_bundle
CONFIG -= qt
QMAKE_CC = gcc -std=c99
SOURCES += main.c
Thanks in advance!
edit: I have added C++ tag, because this error occurs also for C++ console application as in my case.
I have met same problem. Tips and advices on forums are rather clueless, so I investigated problem myself and I have found that it's a bug in QtCreator.
There is dirty little program called qtcreator_process_stub. Whenever you run your program within IDE, IDE first runs qtcreator_process_stub and passes your program name as parameter (among some other parameters). qtcreator_process_stub then starts your program as separate process and prints its PID (and on windows also thread id). Information is printed to the pipe and then it is read by ConsoleProcess::readStubOutput(), which is part of Utils.dll library used by QtCreator.
The problem occurs when "inferior" process (your application) finishes execution before whole communication has been processed. ConsoleProcess::readStubOutput() attempts to use OpenProcess() on non-existing process with closed handle. OpenProcess() fails hence error "Cannot obtain a handle to the inferior: The parameter is incorrect.". Whole error is not handled very gently (Uhm, and now what?)... :-/
Solution:
When you add some user input action, pause, sleep, delay or just some loops, so that execution of your application is a bit longer error vanishes. There is enough time for ConsoleProcess::readStubOutput() to execute OpenProcess(), before your application quits. So as a workaroud I suggest to do that until the bug is fixed.
I got the same error repeatedly while working on a C++ project in Qt. I was able to solve it by copying one of the shared libraries(.dll) I was using in to the build folder.
So, if you are using any shared external libraries that are needed at runtime, make sure they are in the builds folder.

How to launch the associated application for a file / directory / URL?

Linux seems to be easy: xdg-open <file/directory/URL>.
Apparently, Mac is similar: open should be used instead of xdg-open. I don't have access to a Mac so I couldn't test it.
For Windows, I found 4 different suggestions and those that I have tried failed.
Is there a non-java, cross platform way to launch the associated application for a certain file type?
suggests start
How to give focus to default program of shell-opened file, from Java? suggests
cmd /c start ...
How to open user system preferred editor for given file?
How to Find Out Default File Opener with Java?
suggest RUNDLL32.exe
What is the correct way to use ShellExecute() in C to open a .txt
Open file with Windows' native program within C++ code
How to use ShellExecute to open html files in Windows using C++? suggest
ShellExecute
I have tried the first 3 with system() and QProcess::startDetached() and "http://www.stackoverflow.com" as argument but they all failed; start works just fine from the command line though. I haven't tried ShellExecute yet.
What is the Windows equivalent of xdg-open? It seem to me, it is start but why did my attempts with start fail?
Is ShellExecute my only option?
EDIT I thought QDesktopServices::openUrl() was for web pages only because it did not work for files or directories.
After some debugging I figured out that if I replace \\ with / in the path on Windows, it works for files but the directories are still not opened. Any ideas what I am doing wrong?
QDir dir("C:/Documents and Settings/ali");
qDebug() << "Exists? " << dir.exists();
qDebug() << dir.absolutePath();
QDesktopServices::openUrl(QUrl(dir.absolutePath()));
qDebug() << "External app called";
Application Output:
Exists? true
"C:/Documents and Settings/ali"
External app called
But nothing happens, the directory is not opened. On Linux, directories are opened with the default file manager as expected.
SOLUTION: Due to the Qt bug and Windows quirks (malformed application window), I ended up using ShellExecute. That gives me enough flexibility to achieve exactly what I want at some expense...
Why don't you just use Qt's support for this? For example:
QDesktopServices::openUrl(QUrl("/home/realnc/test.pdf"));
This opens the document in Acrobat Reader. In general, it obeys the preferred application settings in my OS for all file types that have one or more applications associated with them. Best of all, it's platform-independent.
Edit:
The fact that it opens directories on Linux but not on Windows smells like a bug. It might be best to report this on Qt's bug tracker. In the meantime, you could have a workaround for Windows for when the file is a directory:
#ifdef Q_WS_WIN
if (QFileInfo(path).isDir())
QProcess::startDetached("explorer", QStringList(path));
else
#endif
QDesktopServices::openUrl(QUrl(path));
You can also do it with cmd.exe's start command, but you'll get an ugly terminal pop up for a few fractions of a second:
QProcess::startDetached("cmd", QStringList() << "/C" << "start"
<< QDir::toNativeSeparators(path));