I was trying to create a style plugin for my project, the plugin seems being loaded, but why QStyleFactory::keys() didn't return my key?
By setting QT_DEBUG_PLUGINS to 1, I got following message :
Found metadata in lib .../styles/libstyles.so, metadata=
{
"IID": "this.is.my.style",
"MetaData": {
"Keys": [
"mystyle"
]
},
"className": "MyStylePlugin",
"debug": true,
"version": 329986
}
in my main():
QApplication app(argc, argv);
QApplication::setStyle(QStyleFactory::create("mystyle"));
qDebug() << QStyleFactory::keys();
The last qDebug statement prints:
Got keys from plugin meta data ()
("Windows", "Fusion") <= Shouldn't "mystyle" also show up here?
That's because your IID should be ""org.qt-project.Qt.QStyleFactoryInterface" not "this.is.my.style". If you change the IID, the plugin is not recognize as a style plugin by Qt.
Here is an extract of Qt code where the keys are detected:
QString iid = library->metaData.value(QLatin1String("IID")).toString();
if (iid == QLatin1String(d->iid.constData(), d->iid.size())) {
QJsonObject object = library->metaData.value(QLatin1String("MetaData")).toObject();
metaDataOk = true;
QJsonArray k = object.value(QLatin1String("Keys")).toArray();
for (int i = 0; i < k.size(); ++i)
keys += d->cs ? k.at(i).toString() : k.at(i).toString().toLower();
}
if (qt_debug_component())
qDebug() << "Got keys from plugin meta data" << keys;
You can see that on the 2nd line if the IID from you plugin does not match the expected IID (d->iid), the code will not bother to try to read the MetaData.
Related
Given unnamed JSON document:
[
{
},
{
},
]
Qt 5.10+ has operator[] for QJsonDocument, so we can address any of them by index:
json_doc[1];
How does one do the same in older versions of Qt?
In your particular example the Json document is represented by a Json array. You might get it like:
if (document.isArray() {
auto a = document.array();
// TODO: check the array size before
auto v = a[0];
}
This is the structure of my json:
{
"images": [
{
"imagename": "banner.jpg",
"shapes": [
]
},
{
"imagename": "banner.png",
"shapes": [
]
},
{
"imagename": "logo.png",
"shapes": [
]
}
]
}
And this is the code I have:
QString filename = jsonFilePath;
QString val;
QFile file;
file.setFileName(filename);
file.open(QIODevice::ReadOnly | QIODevice::Text);
val = file.readAll();
file.close();
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8());
qDebug() << d;
When I run the above code, and try and output d using qDebug() all that is printed to the console is QJsonDocument().
Your code works OK if there are no runtime errors. I'd suggest to check for runtime errors:
Check the return result of file.open().
Use a second argument of QJsonDocument::fromJson() to catch JSON parsing errors and print them like that:
QJsonParseError err;
QJsonDocument d = QJsonDocument::fromJson(val.toUtf8(), &err);
qDebug() << d << err.errorString();
Hope this helps to catch the error.
I would suggest using the toJson() method when printing a QJsonDocument
qDebug() << "Json Document:" << d.toJson();
Good day.
I need to access specific QBS variables inside my Qt code.
An example is the Application's name, organisation or even the flavour, all variables specified like this in my application qbs file.
import qbs
Project {
// These variables should be available in C++ code.
name: "my_app_name"
organization: "Organisation_Name"
flavour:"AppFlavour"
minimumQbsVersion: "1.7.1"
CppApplication {
files: [
]
Depends { name: "Qt"; submodules: ['core', 'network'] }
cpp.cxxLanguageVersion: "c++11"
cpp.defines: [
"QT_DEPRECATED_WARNINGS",
]
consoleApplication: true
Group {
name: "source"
files: [
"qconfigurationmanager.cpp",
]
}
Group {
name: "header"
files: [
"qconfigurationmanager.h",
]
}
Group { // Properties for the produced executable
fileTagsFilter: "application"
qbs.install: true
}
}
}
Looking at the Qt documentation for QBS, I did not find any reference to using QBS variables in Qt code.
This is the only link of using QBS variables, but only within the QBS file
I would like to do this:
QString appflavour = Qbs.get("flavour")
How can I do this?
A possible option is to use a DEFINES and obtain the data through a macro:
import qbs
Project {
minimumQbsVersion: "1.7.1"
property string name: "my_app_name"
property string organization: "Organisation_Name"
property string flavour:"AppFlavour"
CppApplication {
Depends { name: "Qt"; submodules: ['core', 'network']}
cpp.cxxLanguageVersion: "c++11"
consoleApplication: true
cpp.defines: [
"QT_DEPRECATED_WARNINGS",
"name=" + project.name,
"organization=" + project.organization,
"flavour=" + project.flavour
]
...
#define QUOTE_(x) #x
#define QUOTE(x) QUOTE_(x)
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString appname = QUOTE(name);
QString organization = QUOTE(organization);
QString appflavour = QUOTE(flavour);
qDebug()<< appname << organization << appflavour;
...
Output:
"my_app_name" "Organisation_Name" "AppFlavour"
I used to use the build system in Sublime text where I could add my own customize build systems. For example, for CLisp, I created a build system as such:
{
"cmd": ["clisp", "-q", "-modern", "-L", "french", "$file"],
"selector": "source.lisp"
}
Similarly, I had a custom one for C:
{
"cmd" : ["gcc $file_name -Wall -o ${file_base_name} && ./${file_base_name}"],
"selector" : "source.c",
"shell": true,
"working_dir" : "$file_path"
}
How can I do this in Atom?
For tthat task atom has a nice package called Atom Build package, you can find it here: https://github.com/noseglid/atom-build
It is using javascript here is an example for:
module.exports = {
cmd: 'make',
name: 'Makefile',
sh: true,
functionMatch: function (output) {
const enterDir = /^make\[\d+\]: Entering directory '([^']+)'$/;
const error = /^([^:]+):(\d+):(\d+): error: (.+)$/;
// this is the list of error matches that atom-build will process
const array = [];
// stores the current directory
var dir = null;
// iterate over the output by lines
output.split(/\r?\n/).forEach(line => {
// update the current directory on lines with `Entering directory`
const dir_match = enterDir.exec(line);
if (dir_match) {
dir = dir_match[1];
} else {
// process possible error messages
const error_match = error.exec(line);
if (error_match) {
// map the regex match to the error object that atom-build expects
array.push({
file: dir ? dir + '/' + error_match[1] : error_match[1],
line: error_match[2],
col: error_match[3],
message: error_match[4]
});
}
}
});
return array;
}
};
I am stuck on this error. This is my JSON data:
{
"date": "2016-08-26",
"time_of_day": "14:19",
"request_time": "2016-08-26T14:19:59+01:00",
"station_name": "Derby",
"station_code": "DBY",
"departures": {
"all": [
{
"mode": "train",
"service": "22152000",
"train_uid": "C65080"
},
{
"mode": "train",
"service": "22150000",
"train_uid": "C65145"
},
{
"mode": "train",
"service": "22180008",
"train_uid": "C70700"
}
]
}
}
What I am trying to do is add the service json object to an array, after this I want to increment through the service list and add each service to a separate API call. This is my code:
dynamic content = JsonConvert.DeserializeObject(json);
dynamic departures = content.departures;
dynamic DepartTimes = departures.all;
JArray items = ((JArray)DepartTimes["service"]);
int serviceLength = items.Count;
for (int i = 0; i < serviceLength; i++)
{
//next api call containing array increment
}
The error seems to be here :
JArray items = ((JArray)DepartTimes["service"]);
Any help is much appreciated, thank you!
One possible way is -
var json = "json";
dynamic d = JsonConvert.DeserializeObject(json);
JArray arr = new JArray();
foreach(JObject o in d.departures.all){
arr.Add(o["service"]);
}
Console.Write(arr.Count); //output : 3
Provided Json data is not proper. Second and third items must have open curly braces ({)
In addition, an example working code may be:
dynamic content = JsonConvert.DeserializeObject(json));
JArray items = (JArray)content.departures.all;
var newArray = items.Select(x=>x["service"].ToString()).ToArray();