I am just starting to learn about the QResource. As I understand it, it is just a way to create a "directory/File" structure in memory.
I'd like my application to create a resource (at run time) from a raw data. E.g. my application could create a image resulting from some computation and would want to save it as a resource for further usage.
I thought that the constructor:
QResource::registerResource( const uchar * rccData, const QString & mapRoot = QString()
was meant to do that, but I probably missed something as I expected a size argument...
what is rccData then?
How big the the created resource?
How can I create a resource from raw data?
Thanks in advance for your answers.
QResource gives you access to data stored in resource files .qrc. These files inherit a directorylike structure, which then can be accessed through the QResource class. These files can be compiled into the application or can be loaded at runtime via QResource::QResource ( const QString & file = QString(), const QLocale & locale = QLocale() ) consructutor. Those loaded files then virtually repesent a directory structure in memory, but QResource is not meant to create a directory structure out of nothing.
Related
I am attempting to use flatbuffers as a way to communicate between master/slave servers. The issue I am facing is, that after I have read data from char* into flatbuffer, I can't find a way to write it back into char*. First configuration:
flatc --cpp --gen-mutable --gen-object-api -o ${OUT} ${IN}
And here is code which bothers me:
char* buffer = <MY_FLATBUFFER_DATA>;
auto managedObject = GetMutableManagedObject(buffer);
makeChanges(managedObject);
char* newBuffer = managedObject.deserialize(); // This is my imaginative method
I want to be able to deserialize object which has been modified and send it back to the slave. Is it possible? Or I have to use "slower" (as it describes tutorial) Pack/UnPack methods?
(I do not mind another approach kind of answer)
Yes, you need Pack/UnPack. --gen-mutable only allows very limited modification (some scalars), if you want to be able to modify everything you need the object api.
As I understand it, the way to packages non-code resources such as data files in a Qt app is using the resource system. However, what if I want to access a resource using a non-Qt function. For example, I may have a .txt or .csv file with some application data that I want to accessing using ifstream. It doesn't seem to work to use the ": ..." syntax in place of a filename for non-Qt functions and classes. Is there a separate workflow for packaging data used by non-Qt functions in an app?
I'm using OSX, but I would assume these issues are platform independent.
The sole purpose of the Qt resource system is to bundle data within the executable itself. If you wish not to integrate the data in the executable, then you simply must not use the resource system.
On mac, if you wish to add "data.txt" from project source to your application bundle, but not to the executable itself, add the following to your .pro file:
mac {
BUNDLE = $$OUT_PWD/$$TARGET$$quote(.app)/Contents
QMAKE_POST_LINK += ditto \"$$PWD/data.txt\" \"$$BUNDLE/Resources/\";
}
Given the above project file, use the QCoreApplication::applicationDirPath() for a path useful in getting to the file:
#include <QCoreApplication>
#include <QFile>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
qDebug() << QCoreApplication::applicationDirPath();
QFile data(QCoreApplication::applicationDirPath() + "/../Resources/data.txt");
if (data.open(QIODevice::ReadOnly | QIODevice::Text))
qDebug() << data.readAll();
return 0;
}
In the above example, the Resources folder has nothing to do with the Qt resource system. It's simply a naming convention in OS X application bundles. We're not using the Qt resource system here.
If you wish to use the Qt resource system and access the resource data directly and not through a QFile, the QResource class provides access to resources that are bundled in the executable.
If the code under your control insists on using ifstream for data input, then it's artificially limited and should be fixed. It should use istream instead, as that class can be backed by anything, not necessarily a file. If it's code that you don't control, you could set up the ifstream on a QLocalSocket.
You can map the constant QResource::data() to an input stream via a stream buffer.
If the resource isCompressed(), then you need to first decompress it to a temporary area. You can also disable resource compression to avoid the decompression step. You can use a whole-executable compressor like upx instead - by the time your code runs, everything will be already decompressed and ready to use.
You can copy the resource file into a temporary folder. To do this, use a QTemporaryDir which creates a temporary folder and deletes it automatically when the program is finished. To access the path of that folder, use the QTemporaryDir::path() method. Here is an example of how you can use it:
#include <QTemporaryDir> //You need to include this header
QTemporaryDir temporaryDir;
//Copy the resource file into the temporary folder
QFile::copy(":/exampleprefix/examplefile.txt", temporaryDir.path() + "/examplefile.txt");
//Read the file
std::ifstream fileStream(QString(temporaryDir.path() + "/examplefile.txt").toLatin1().data());
//etc
What about opening the resource file with a QFile object, wrapping this with a QDataStream object, and wrapping this with a boost::iostreams::stream object, which derives from a specialization of std::basic_istream? Sounds complicated, but does not need too many lines of code, see this answer.
I'm an unfortunate beginner at C++ and using the Qt GUI designer program seemed perfect for my needs, except I'm having problems trying to write out the code necessary for this. I could use the QSettings string to store local settings on the hard drive, but I personally hate it when programs do the %HOME_LOCAL%\APPS_SETTINGS bull that some do. I need to save a text file for both settings and a local\host database, within the program directory, to remember strings to read from later.
What is the line of code I need to make use of a local host text database or is there a better option? And how can I store that with the local program inside its directory?
You can use QSettings with any file, with constructor QSettings::QSettings ( const QString & fileName, Format format, QObject * parent = 0 ).
To get the program directory, you can use QCoreApplication::applicationDirPath().
So, answer to your question, statement to put after creation of QApplication instance:
QSettings *settings = new QSettings(
QCoreApplication::applicationDirPath() + "/settings.ini",
QSettings::IniFormat,
qApp);
But, as noted in the comments under question, if you're making your program for general distribution, you should use the OS default. Examine all the constructors of QSettings to see what it can do. User does not often have write permission in the application directory. Note that you can also store settings to Windows registry with QSettings::NativeFormat.
I'm new to MFC, once I create my first app, in myApp::InitInstance() . I have
SetRegistryKey(_T("Local AppWizard-Generated Applications"));
Can I delete this and save settings to my own ini construct ?
Edit: After further testing, the solution below does not work if your app class is derived from CWinAppEx ! It does work if your app is directly derived from CWinApp.
To store values in an .ini file instead of the registry:
Omit the call to SetRegistryKey.
In your app class, set m_pszProfileName to the full path of your .ini file. The filename string must be allocated using malloc, because the framework will call free on it when your app shuts down. First free the existing value, then assign your new string:
free((void*)m_pszProfileName);
m_pszProfileName = ::_tcsdup(_T("C:\\somedir\\myini.ini"));
Call CWinApp::GetProfileInt, CWinApp::WriteProfileInt and similar functions as usual.
I strongly recommend using a path under APPDATA for storing your .ini file.
Yes you can. CWinApp::SetProfileXXX() does this for you, actually - but I wouldn't use these methods anymore in 2010, they were OK when ppl moved from .ini to the registry.
I am not sure if this is possible as a .ini file has only strings for your program. You can create an operating system script (.bat for windows, .sh for unix etc) and call it using system() call.
Use win32 APIs WriteProfileString (write to INI file) and GetProfileString (read from INI file)
For more help
ms-help://MS.MSDNQTR.v90.en/sysinfo/base/writeprofilestring.htm
Does Qt has something like QSettings, but for local scopes?
I am seeking for a data structure with the same methods, but not specific for APPLICATION.
I mean, I want to construct local (for example, exporting settings) settings from file (xml, for example) and use them in local scope - without polluting global application settings.
Is that possible (with QSettings or some other class)? How should I construct the object then?
You can use
void QSettings::setPath ( Format format, Scope scope, const QString & path )
to set the format (as specified in the doc)
QSettings::NativeFormat 0 Store the
settings using the most appropriate
storage format for the platform. On
Windows, this means the system
registry; on Mac OS X, this means the
CFPreferences API; on Unix, this means
textual configuration files in INI
format.
QSettings::IniFormat 1 Store the
settings in INI files.
QSettings::InvalidFormat
the scope:
QSettings::UserScope 0 Store settings
in a location specific to the current
user (e.g., in the user's home
directory).
QSettings::SystemScope 1 Store
settings in a global location, so that
all users on the same machine access
the same set of settings.
So if you are on Windows and want to write User-specific settings, you would use the IniFormat and the UserScope values and specify the path where you want to write your settings in the path variable.
Hope this helps.
You create a datastream and write the data into the file in member by member fashion.