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");
Related
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.
I'm using QSystemTrayIcon to display notification in Windows 10.
Along with the notification, the application name is also displayed.
The problem here is the app name is displayed along with the extension(.exe).
How can the extension(.exe) be removed from the notification?
Try adding this line to your .pro file:
QMAKE_TARGET_DESCRIPTION = "Whatever"
It should change the process name (both in the notifications and in the task manager) to "Whatever".
More variables like this can be found here: Qmake Variables Documentation
Note from the documentation:
This is only utilized if the VERSION or RC_ICONS variable is set and the RC_FILE and RES_FILE variables are not set.
Step-by-step instructions for creating a test application
Create Qt Widgets Application project, containing a QWidget based widget
Create images directory in the project folder, put an icon file into it (for this example let it be icon.ico)
Add a resource file to the project
To that resource file add prefix /, then "Add Files", selecting ./images/icon.ico
In main.cpp change the code to following:
#include "widget.h"
#include <QApplication>
#include <QIcon>
int main(int argc, char *argv[])
{
QCoreApplication::setApplicationName(APP_NAME);
QApplication a(argc, argv);
a.setWindowIcon(QIcon(":/images/icon.ico"));
Widget w;
w.setWindowTitle(qApp->applicationName());
w.setWindowIcon(qApp->windowIcon());
w.show();
return a.exec();
}
In widget.cpp change code to following:
#include "widget.h"
#include "ui_widget.h"
#include <QSystemTrayIcon>
Widget::Widget(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget)
{
ui->setupUi(this);
QSystemTrayIcon *trayIcon = new QSystemTrayIcon(qApp->windowIcon(), this);
trayIcon->show();
connect(trayIcon, &QSystemTrayIcon::activated, [=]() {
trayIcon->showMessage("Title", "Message");
});
}
Widget::~Widget()
{
delete ui;
}
To the bottom of the project (.pro) file add following:
DEFINES += APP_NAME=\\\"AppName\\\"
QMAKE_TARGET_DESCRIPTION = "Whatever"
win32:RC_ICONS += images/icon.ico
Save, run qmake (Build -> Run qmake), rebuild project
Start the application. Now the window title should be "AppName", which came from APP_NAME define, both window and tray icon - icon.ico, and the process name in task manager and notifications - "Whatever". You can make the app display a notification by clicking on the tray icon. Notification should look like this:
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;
}
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.
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.