I am importing 2 QML files that come with Qt Controls - ScrollBar.qml and Button.qml in my project. I pre-compile all .qml files that I wrote to reduce application launch time. Is there a way to pre-compile these 2 QML files that come as part of the package?
I tried to remove these files from the qml/QtQuick/Controls/ path and placed them in the same folder as my .qml files but it still failed to load. When I reference ScrollBar in my code, it always tries to load ScrollBar.qml from qml/QtQuick/Controls/ path.
Does any one know if it is possible to pre-compile these QMLs at all? If yes, has any one successfully done it?
Appreciate any help. Thank you.
I'm assuming that you're referring to the Qt Quick Compiler as pre-compiling. The simplest way would just be to build the entire Qt Quick Controls module with the Qt Quick Compiler.
If you need to have it within your project, you could try adding an import that contains the Qt Quick Controls import. QQmlEngine::addImportPath() says:
The newly added path will be first in the importPathList().
That statement seems to imply that order matters, and the code confirms it:
QStringList localImportPaths = database->importPathList(QQmlImportDatabase::Local);
// Search local import paths for a matching version
const QStringList qmlDirPaths = QQmlImports::completeQmldirPaths(uri, localImportPaths, vmaj, vmin);
for (const QString &qmldirPath : qmlDirPaths) {
QString absoluteFilePath = typeLoader.absoluteFilePath(qmldirPath);
if (!absoluteFilePath.isEmpty()) {
QString url;
const QStringRef absolutePath = absoluteFilePath.leftRef(absoluteFilePath.lastIndexOf(Slash) + 1);
if (absolutePath.at(0) == Colon)
url = QLatin1String("qrc://") + absolutePath.mid(1);
else
url = QUrl::fromLocalFile(absolutePath.toString()).toString();
QQmlImportDatabase::QmldirCache *cache = new QQmlImportDatabase::QmldirCache;
cache->versionMajor = vmaj;
cache->versionMinor = vmin;
cache->qmldirFilePath = absoluteFilePath;
cache->qmldirPathUrl = url;
cache->next = cacheHead;
database->qmldirCache.insert(uri, cache);
*outQmldirFilePath = absoluteFilePath;
*outQmldirPathUrl = url;
return true;
}
}
Your project structure might look something like this:
myproject/
qml/
main.qml
QtQuick/
Controls/
Button.qml
ScrollBar.qml
qmldir
In main.cpp you'd set the path to the qml directory (note that the path will be different depending on whether you're doing an in-source build or a shadow build of your project, so you may want to use a resource file to simplify things):
engine.addImportPath("path/to/qml");
Note that the controls import other types. For example, Button uses the Settings singleton, which comes from the QtQuick.Controls.Private import, so you'd need to copy that into the qml directory, too. Settings loads a certain style for the button (ButtonStyle), which could be any of the styles in this folder, depending on which style is in use.
In short, you need to copy all of the potential dependencies of the QML files you're using.
Related
I'm making an application part of which is reading from an XML which stores some preferences. However, whenever I build the project, all the sources get copied but the preferences file does not! I have added the following to the .pro file -
RESOURCES += rsc.qrc
And my rsc.qrc contains
<!DOCTYPE RCC><RCC version="1.0">
<qresource>
<file>data/preferences.xml</file>
<file>data/gamedata.xml</file>
</qresource>
</RCC>
Now whenever I try to open preferences.xml
QFile preferences(":/data/preferences.xml");
if(!preferences.exists()){
preferences.open(QFile::WriteOnly);
preferences.write("abc");
qDebug() << "Written";
}
else {
qDebug() << "File exists";
}
Absolutely nothing gets printed and even the rest of the application stops working.
You don't use the resource part correctly in your example.
It will most likely not work because you try to write to a resource that is embedded into your executable after you have build your application. Reading is fine, but writing can't work by definition.
If you want a editable setting files, you have to distribute them along with your executable, or use a different method for reading/writing your settings like QSettings.
However using QSettings also means, that you will need to configure all your default settings in your loading function in case the values do not exist if you use the default configuration. Meaning you use registry on windows.
You have the option to force the use of a INI file format in the constructor of QSettings, this can make sense if you want to provide a default settings INI file instead of your xml files.
In case you want to store more complex data a xml file might be needed anyway, so if you want to stick with that you will need a way to copy your setting files to your build path. This can be done within your pro file with QMAKE_POST_LINK.
Example:
COPY_CMD = "$$PWD\\data\\preferences.xml $$OUT_PWD\\release\\data\\preferences.xml"
COPY_CMD = $${QMAKE_COPY} $$replace( COPY_CMD, "/", "\\" ) $$escape_expand( \\n\\t )
QMAKE_POST_LINK += $$COPY_CMD
I'm new to learning the Qt library, and I'm having a hard time getting QFileDialog to work properly. I want the user to be able to select a directory but also be able to view the files and folders so they know which directory they should pick. I have seen things similar to this being posted elsewhere but everything I've tried hasn't made any difference in the output.
I've tried creating my own dialog and setting the mode to directory, which says that it should display both files and folders:
QFileDialog myDialog(this);
myFileExplorer.setFileMode(QFileDialog::Directory);
myFileExplorer.setDirectory("C:/");
QString file = myFileExplorer.exec();
And I've tried using getExistingDirectory as well, but with that function it always only shows the directory as well.
Thanks
QString getExistingDirectory ( QWidget * parent = 0, const QString & caption = QString(),
const QString & dir = QString(), Options options = ShowDirsOnly )
The default options parameter is set to show dirs only, you have to change it to
QFileDialog::DontUseNativeDialog
But unfortunately you won't be able to use native dialog.
I am new to Ubuntu & Qt. I need to show busy status for other long operations. So, I was just trying to use waiting animation gif files to load instead using Progress bars.
I am using Eclipse Editor for Qt project.
Trolltech/../imageformat folder contains libqgif.so and libqgif.so.debug. I have copied these files in my debug folder too.
loader.gif is added in qrc file and kept in /Resources folder
IN MainWindow class I have added label and after setupUi(this) been called I call my ShowMovie() function as below:
ShowMovie() {
QMovie *movie = NULL;
movie = new QMovie(":/Resources/loader.gif");
if(movie->isValid()) {
ui.label_3->setMovie(movie);
movie->start();
}
else
qDebug()<<"Movie is Invalid";
qDebug()<<QImageReader::supportedImageFormats ();
}
Always isValid() function returns false & I got message that Movie is Invalid.
Last qDebug() returns
("bmp", "gif", "ico", "jpeg", "jpg", "mng", "pbm", "pgm", "png", "ppm",
"svg", "svgz", "tif", "tiff", "xbm", "xpm")
i.e means gif support is available.
I have tried to call ShowMovie() function before loading Main UI and/or on button clicked. Both fails.
Provide help on what is to be corrected.
Thank you.
you don't need to copy librairies files *.so.
Try creating the movie object with the full path to loader.gif. Does it work?
Then you have not setup correctly your resource system.
Either you have a syntax mistake in the qrc file which need to be fixed or you forgot to add it as a resource in the project file (.pro) using
RESOURCES = myqresource.qrc
If I want to load file directly (QImage i1("image1.jpg");) where should I store it?
If I have to give full path of file or only short path is required?
If you don't want to worry about an image (and you are not having too much of them), consider using Qt Resources. Qt Resources will embed the image into the executable independent of the platform. The images would be pulled from the filesystem at compile time, and an IDE like Qt Creator actually helps you with that.
E.g. if you created an resource called "image" containing your file, you could reference your image by typing
QImage(":/images/image1.jpg")
If you want to use QImage as you have written in your question, then your image needs to be in your current directory. Most likely that will be the directory where your executable is stored.
Otherwise you will have to give either a relative or full path.
Use the absolution path or copying the image1.jpg to the current path.
My current path in qt creator is not same as *.exe, but its parent (debug/Release). Use the below code to find.
QString fileName = QFileDialog::getOpenFileName(this,
tr("Open Image"),
QDir::currentPath(),
tr("Image Files (*.png *.jpg *.bmp)"));
I'm trying to do a very simple app in Flash/Flex, that loads an image embedded in the swf itself and then shows it. The thing is I'm trying to do it using the command line only (mxmlc and compc) and without using #Embed, and failing miserably.
I have a very simple Main.as :
package
{
import flash.display.*;
import flash.utils.*;
public class Main extends Sprite
{
public function Main () : void
{
var pDef:Class = getDefinitionByName("icon_big.png") as Class;
var _image:BitmapData = new pDef(0, 0);
var pSprite:Sprite = new Sprite();
pSprite.graphics.beginBitmapFill(_image);
pSprite.graphics.drawRect(0, 0, _image.width, _image.height);
pSprite.graphics.endFill();
addChild(pSprite);
}
}
}
This works fine if I add icon_big.png to the Library using the Flash IDE, but I can't figure out how to do it from the command line.
I'm using compc to put the png inside a swc :
compc --include-file icon_big.png icon_big.png -output assets.swc
This generates a 17 kb assets.swf, slightly bigger than icon_big.png. Then I try to compile and link Main.as :
mxmlc -include-libraries+=assets.swc Main.as
This produces a 944 byte Main.swf, which clearly doesn't include the asset, and fails at runtime.
According to the mxmlc docs I found, -include-libraries should link with every class, including the ones not directly referenced by code (as is the case here, since I'm getting the class from code), and it unsurprisingly fails at runtime.
Note that this same code (or, more precisely, quite equivalent code) works when used within a Flash project - I'm not looking to fix the code, but how to do in the command line whatever Flash does internally.
I feel I'm just "not getting" something... any clues?
I recommend you to download the swftools from swftools.org. Once you have them, run:
swfdump -D assets.swf
Take a look in particular at the output which relates to SWF tag with value 76 (0x4C), called SYMBOLCLASS.
Here is an example of an exported class, named IntegerMemberBySlot:
[04c] 24 SYMBOLCLASS
exports 0001 as "IntegerMemberBySlot"
What symbols are you exporting from your assets.swf?
Have you tried adding the path of the assets to your source path parameter when compiling with mxmlc?
-source-path ./PATH/TO/ASSET
I think you need to embed the PNGs in a class, then compile that class into a SWC. I don't think you can put the PNGs directly into a SWC like you are trying to, but I could be wrong.
I had a similar situation (large project, resource swc with graphic assets), and no matter what I tried, I could't get Flex to include assets and classes not directly referenced from the project (I wanted to include different skins, and then instantiate the proper one at runtime, depending on the configuration).
Finally, I found a workaround by instead of static swc liking, switching over to runtime shared libraries (RSLs). Basically, flex unbundles the swc, and loads and links the included swf in runtime, before running the application itself. All of the classes and assets in the swf are loaded this way. May not be exactly what you're after, but it works for me.