QProcess: Destroyed while process (Web Browser) is still running - qt

Is it possible to close a window or tab in an external browser after starting it using a Qprocess?
I tried the following (for example):
#include <QCoreApplication>
#include "QProcess"
#include "QThread"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QProcess process;
process.start("C:/Program Files/Google/Chrome/Application/Chrome.exe", QStringList() << "google.com");
QThread::msleep(1000);
process.kill();
process.waitForFinished();
return a.exec();
}
But the process is not closed.
So, Is it not possible or there is a workaround? thanks.

Well this is not the best solution but I here it is:
QProcess::execute("taskkill", QStringList() << "/IM" << "chrome.exe" << "/F");
It only works on windows system and closes all browser windows but that is the only solution I have reached and will use for now.

Related

QT WebGL-stream, virtualKeyboard and touch screen problem

As I see, the virtualKeyboard (plugin) sends touch and click event when qml application is running over WegGL-stream. Now I've trouble finding an easy workaround.. Does anyone have a good idea? Further is it a virtualKeyboard or a QPA-Plugin bug?
Tried with QT 5.13.0, MSVC2017 64Bit / MinGW 64Bit compiler, Windows10, Chrome 76.0.3809.132 64Bit / Firefox. If application is not running over WebGL-stream, everthing works fine in terms of touch and click events.
// Tests with QT Quick Virtual Keyboard example with extended main.cpp..
int main(int argc, char *argv[])
{
qputenv("QSG_RENDER_LOOP","threaded");
qputenv("QT_QPA_PLATFORM", "webgl:port=1051");
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QGuiApplication app(argc, argv);
QQuickView view(QString("qrc:/%2").arg("basic-b2qt.qml"));
if (view.status() == QQuickView::Error)
return -1;
view.setResizeMode(QQuickView::SizeRootObjectToView);
view.show();
return app.exec();
}

QDesktopServices::openUrl does not work, neither for URLs nor for local files, on two platforms

I have a code as simple as this:
int main() {
QUrl url("http://google.com");
if (!QDesktopServices::openUrl(url) )
qDebug() << "Failed to open url";
return 0;
}
Running the code gives "Failed to open url". Tried on Ubuntu with Qt 5.5.1 and on MS Windows with Qt 5.7. No difference.
Local files also do not open:
int main() {
QString file = "/home/user/testfile.pdf";
if (!QDesktopServices::openUrl( QUrl::fromLocalFile(file) ) )
qDebug() << "Failed to open file";
return 0;
}
Again, "Failed to open file". On both Ubuntu and Windows. I can see some discussion in stackoverflow about openUrl, but they are concerned with specific features, such as failing to open urls with spaces, etc. But here it just doesn't work at all, on two independent platforms. What do I miss?
QDesktopServices is part of the Qt GUI module. Therefore, in order to use any function related to QDesktopServices, you will need to instantiate at least a QGuiApplication :
Since the QGuiApplication object does so much initialization, it must
be created before any other objects related to the user interface are
created.
In fact, you can create a QApplication (as #Alex Spataru suggested), since it inherits QGuiApplication. To make your code work, you just need this :
int main(int argc, char *argv[]) {
QApplication app(argc, argv); // just this line
QUrl url("http://google.com");
if ( !QDesktopServices::openUrl(url) )
qDebug() << "Failed to open url";
return 0;
}

Qt, QCoreApplication and QFtp

I want to use QFtp for the first time and googled a lot to find out how it should be used. This, among others is a typical example:
#include <QCoreApplication>
#include <QFtp>
#include <QFile>
int main(int argc, char ** argv)
{
QCoreApplication app(argc, argv);
QFile *file = new QFile( "C:\\Devel\\THP\\tmp\\test.txt" );
file->open(QIODevice::ReadWrite);
QFtp *ftp = new QFtp();
ftp->setTransferMode(QFtp::Active);
ftp->connectToHost("ftp.trolltech.com");
ftp->login();
ftp->cd("qt");
ftp->get("INSTALL",file);
ftp->close();
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit()));
int ret = app.exec();
delete ftp;
delete file;
return ret;
}
The question:
As far as I understood, the QCoreApplication app is needed to handle the "done" signal, emmited upon finalization of ftp-get. Now, the ftp->get is called before the connect and even before the app handler is running at all (app.exec() is called afterwards).
What happens, if the file transfer has completed already before the "connect" statement? In fact, that will not happen, but I could put an artificial delay of, say 1 minute between ftp->close() and the connect(...). During this time, the ftp get will surely be finished. What would happen?
Note that QFtp is really only meant for legacy Qt applications and it is now suggested that QNetworkAccessManager and QNetworkReply are used instead, as detailed in the Qt documentation.
That being said, with your connect call being positioned after the connection to the FTP site and retrieving of the file, should the file be downloaded first, the 'quit' signal would never be reached. If you make the connection straight after creating the QFtp object, then this won't be an issue: -
QFtp *ftp = new QFtp();
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit()));
This guarantees that the 'quit' slot will be called when the QFtp object emits the 'done' signal.
QFtp *ftp = new QFtp();
QObject::connect(ftp, SIGNAL(done(bool)), &app, SLOT(quit()));
ftp->setTransferMode(QFtp::Active);
ftp->connectToHost("ftp.trolltech.com");
ftp->login();
ftp->cd("qt");
ftp->get("INSTALL",file);
ftp->close();
int ret = app.exec();
In reality though, I would expect the connect in your example would complete before the machine had time to negotiate a connection to another server, login and start the download of the file.

Unzipping file throws no archive found error with Qt5

I have implemented a code that creates a zip file. The zip file gets successfully created but however when I manually (without code) try and check the contents of the zip file by unzipping it, I get an error saying No archive found and the unzipping process stops.. Why is this problem occuring.
Here is my code
#include <QCoreApplication>
#include <QByteArray>
#include <QBitArray>
#include <QString>
#include <QDebug>
#include <QFile>
void Zip(QString filename , QString zipfilename);
int main(int argc, char *argv[]){
QCoreApplication a(argc, argv);
Zip("C:\\programs\\zipping_qt\\sample.txt",
"C:\\programs\\zipping_qt\\samples.zip");
qDebug() << "Done zipping";
return a.exec();
}
void Zip (QString filename , QString zipfilename){
QFile infile(filename);
QFile outfile(zipfilename);
infile.open(QIODevice::ReadOnly);
outfile.open(QIODevice::WriteOnly);
QByteArray uncompressedData = infile.readAll();
QByteArray compressedData = qCompress(uncompressedData,9);
outfile.write(compressedData);
infile.close();
outfile.close();
}
qCompress does not create zip files. It uses zlib to create a compressed data block. Such blocks can only be directly decompressed by using qUncompress, or by calling zlib directly. There's no standard stand-alone utility that does such decompression. Not even gunzip does it, since zlib-style API uses different headers than gzip.
There are some other nitpicks about your code:
There's no need to call a.exec() if you don't need to run the event loop.
There's no need to explicitly close the files, since QFile is a proper C++ class and implements RAII.
You never check if open, readAll or write succeeds.

How to load qml file from resources, using QtQuick 2 Controls

I have created Qt Quick 2 Controls project, added resource, placed my qml-file inside resource and added alias to this file. Now I'm wondering, why does next code can't load qml-file as main qml-file:
#include <QDebug>
#include <QFile>
#include <QByteArray>
#include "qtquick2controlsapplicationviewer.h"
int main(int argc, char *argv[]) {
Application app(argc, argv);
QString fileInResource(":main/mainQml");
QFile f(fileInResource);
if (!f.exists()) {
qDebug() << "No file";
} else {
f.open(QIODevice::ReadOnly);
qDebug() << f.readAll();
}
QtQuick2ControlsApplicationViewer viewer;
viewer.setMainQmlFile(fileInResource);
viewer.show();
return app.exec();
}
Since in case of QFile usage, it reads file correct and output whole file, but viewer said:
file:///path/:main/mainQml:-1 File not found
QQmlComponent: Component is not ready
Error: Your root item has to be a Window.`
How to make viewer load my qml-file?
UPD: Added minimal working example -- download it here
The problem is in
void QtQuick2ApplicationViewer::setMainQmlFile(const QString &file)
It uses
setSource(QUrl::fromLocalFile(d->mainQmlFile));
for setting source, and QUrl::fromLocalFile messes up the path. Just change it to
setSource(QUrl(d->mainQmlFile));
and everything works.
UPD:
In your example it's actually component.loadUrl(QUrl::fromLocalFile(d->mainQmlFile));, line 80.
No file file:///path/qrc:/main/mainQml <-
try change the code like below and make sure main.qml file exists in resource .qrc file
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("utils", &qmlUtils);
engine.load(QUrl(QStringLiteral("qrc:///main.qml")));
or like this if you are not using the QQmlApplicationEngine
Application app(argc, argv);
QString fileInResource("qrc:///main.qml");

Resources