Im learning how to use QT's translate stuff for the first time for work.
They already have things working to some degree and its my job to clean
things up and get it working properly as well as using lupdate to keep
things in sync when they change etc. We are also using QML in which we
wrote a wrapper function for all our strings, so lupdate does not find
our function to add to the .ts XML file. The reason we use a wrapper is
for centralizing other functions at once place for all strings. We also
dont always use a string literal in our 'source' argument but a defined
property, such as:
property string buttonTxt: "ButtonText"
then: commonTRFunction(context, buttonTxt)
which of course lupdate does not find for both reasons.
Ive looked into updating the lupdate source very briefly
and Im not sure if its worth trying to hack it to find our function or
write our own parser to find the standard QT tags AND also our new ones?
Secondly, and related to the first part, Id like a way to make one
context section that contains all the common words we use in our app
such as 'Back', 'Save', 'Ok' etc etc without repeating it over and over
throughout the .ts file. lupdate seems to repeat things over and over
in multiple contexts which seems both inefficient and a waste of lines
in the ts file.
I haven't found any QT docs that really explain the differences between tr(), qsTr(), qsTranslate(), QT_TR_NOOP() and QT_TRANSLATE_NOOP(). I know you sometimes need a context and the source,
and other times just use the source without a context. We dont use
the disambigous arg. Most of our code is in QML and not C++.
Also we are running lupdate from the command line.
Does anyone have thoughts, suggestions or even a tool someone wrote
that can be used for what we have? I appreciate your help.
Related
I am currently working with python and Qt which is kind of new for me coming from the C++ version and I realised that in the oficial documentation it says that an UI file can be loaded both from .ui or creating a python class and transforming the file into .py file.
I get the benefits of using .ui it is dynamically loaded so no need to transform it into python file with every change but what are the benefits of doing that?, Do you get any improvements in run time? Is it something else?
Thanks
Well, this question is dangerously near to the "Opinion-based" flag, but it's also a common one and I believe it deserves at least a partial answer.
Conceptually, both using the pyuic approach and the uic.loadUi() method are the same and behave in very similar ways, but with some slight differencies.
To better explain all this, I'll use the documentation about using Designer as a reference.
pyuic approach, or the "python object" method
This is probably the most popular method, especially amongst beginners. What it does is to create a python object that is used to create the ui and, if used following the "single inheritance" approach, it also behaves as an "interface" to the ui itself, since the ui object its instance creates has all widgets available as its attributes: if you create a push button, it will be available as ui.pushButton, the first label will be ui.label and so on.
In the first example of the documentation linked above, that ui object is stand-alone; that's a very basic example (I believe it was given just to demonstrate its usage, since it wouldn't provide a lot of interaction besides the connections created within Designer) and is not very useful, but it's very similar to the single inheritance method: the button would be self.ui.pushButton, etc.
IF the "multiple inheritance" method is used, the ui object will coincide with the widget subclass. In that case, the button will be self.pushButton, the label self.label, etc.
This is very important from the python point of view, because it means that those attribute names will overwrite any other instance attribute that will use the same name: if you have a function named "saveFile" and you name the button "saveFile", you won't have any [direct] access to that instance method any more as soon as setupUi is returned. In this case, using the single inheritance method might be helpful - but, in reality, you could just be more careful about function and object names.
Finally, if you don't know what the pyuic generated file does and what's it for, you might be inclined to use it to create your program. That is wrong for a lot of reasons, but, most importantly, because you might certainly realize at some point that you have to edit your ui, and merging the new changes with your modified code is clearly a PITA you don't want to face.
I recently answered a related question, trying to explain what happens when setupUi() is called in much more depth.
Using uic.loadUi
I'd say that this is a more "modular" approach, mostly because it's much more direct: as already pointed out in the question, you don't have to constantly regenerate the ui files each time they're modified.
But, there's a catch.
First of all: obviously the loading, parsing and building of an UI from an XML file is not as fast as creating the ui directly from code (which is exactly what the pyuic file does within setupUi()).
Then, there is at least one relatively small bug about layout contents margins: when using loadUi, the default system/form margins might be completely ignored and set to 0 if not explicitly set. There is a workaround about that, explained in Size of verticalLayout is different in Qt Designer and PyQt program (thanks to eyllanesc).
A comparison
pyuic approach
Pros:
it's faster; in a very simple test with a hundred buttons and a tablewidget with more than 1200 items I measured the following bests:
pyuic loading: 33.2ms
loadUi loading: 51.8ms
this ratio is obviously not linear for a multitude of reasons, but you can get the idea
if used with the single inheritance method, it can prevent accidental instance attribute overwritings, and it also means a more "contained" object structure
using python imports ensures a more coherent project structure, especially in the deployment process (having non-python files is a common source of problems)
the contents of those files are actually instructive, especially for beginners
Cons:
you always must remember to regenerate the python files everytime you update an ui; we all know how easy is to forget an apparently meaningless step like this might be, expecially after hours of coding: I've seen plenty of situations for which people was banging heads on desks (hopefully both theirs) for hours because of untraceable issues, before realizing that they just forgot to run pyuic or didn't run it on the right files; my own forehead still hurts ;-)
file tracking: you have to count two files for each ui, and you might forget one of them along the way when migrating/forking/etc, and if you forgot an ui file it possibly means that you have to recreate it completely from scratch
n00b alert: beginners are commonly led to think that the generated python file is the one to be used to create their programs, which is obviously wrong; unfortunately, the # WARNING! message is not clear enough (I've been almost begging the head PyQt developer about this); while this is obviously not an actual problem of this approach, right now it results in being so
some of the contents of a pyuic generated files are usually unnecessary (most importantly, the object name, which is used only for specific cases), and that's pretty obvious, since it's automatically generated ("you might need that, so better safe than sorry"); also, related to the issue above, people might be led to think that everything pyuic creates is actually needed for a GUI, resulting in unnecessary code that decreases its readability
loadUi method
Pros:
it's direct and immediate: you edit your ui on Designer, you save it (or, at least, you remember to do it...), and when you run your code it's already there; no fuss, no muss, and desks/foreheads are safe(r)
file tracking and deployment: it's just one file per ui, you can put all those ui files in a separate folder, you don't have to do anything else and you don't risk to forget something on the way
direct access to widgets (but this can be achieved using the multiple inheritance approach also)
Cons:
the layout issue mentioned above
possible instance attribute overwriting and no "ui" object "containment"
slightly slower loading
path and deployment: loading is done using os relative paths and system separators, so if you put the ui in a directory different from the py file that loads that .ui you'll have to consider that; also, some package managers use to compress everything, resulting in access errors unless paths are correctly managed
In my opinion, all considering, the loadUi method is usually the better choice. It doesn't distract me, it allows better conceptual compartmentation (which is usually good and also follows a pattern similar to MVC much more closely, conceptually speaking) and I strongly believe it as being far less prone to programmer errors, for a multitude of reasons.
But that's clearly a matter of choice.
We should also and always remember that, like every other choice we do, using ui files is an option.
There is people who completely avoids them (as there is people who uses them literally for anything), but, like everything, it all and always depends on the context.
A big benefit of using pyuic is that code autocompletion will work.
This can make programming much easier and faster.
Then there's the fact that everything loads faster.
pyuic6-Tool can be used to automate the call of pyuic6 when the application is run and only convert .ui files when they change.
It's a little bit longer to set up than just using uic.loadUi but the autocompletion is well worth it if you use something like PyCharm.
I would like to add a new language (called 'kiwi') into the Brackets code editor which is based on C++. It uses the exact same rules but has additional keywords.
I've already done the part of adding the additional keywords with separate syntax highlighting directly on the clike.js file but i don't really like directly modifying the def for C++
Can someone explain to me how I can achieve this? I don't really understand the difference between using def() and CodeMirror.defineMIME(). If this new language will take cpp/hpp input files, how will the editor switch from C++ -> kiwi?
Thanks in advance
Patching your local copy of the code, as you've done, might be perfectly fine for your needs. (And if you run from a Git copy of the source, it's easy to pull down updates without losing your local diffs).
If you want to do it a "cleaner" way, you can write a Brackets extension to define the new language - this way the change is easily shareable with others, and updating Brackets is even easier.
The way you'd do this roughly follows the Defining a new language docs:
Write an extension to package up your code that will define the new language (below)
The CM mode "clike" is already loaded, so you don't need to worry about that
Call CodeMirror.defineMIME() to set up a clike configuration with the right list of keywords - using a new mimetype name of your choosing. (Looking at the def() code in clike.js, I don't think the extra stuff it does is especially relevant for Brackets).
Call LanguageManager.defineLanguage() to tell Brackets about your new language mode (and what file extensions map to it, etc.). You should be able to mostly copy how the C++ mode is defined here - except with your new MIME name instead.
You should read CodeMirror documentation to find out about writing your modes.
But in short you can define your own type of clike language, by using CodeMirror.defineMIME().
You also asked what's the difference between def() and CodeMirror.defineMIME(). If you look at the code you can see that def() function is calling CodeMirror.defineMIME() at the end, so I believe it is just a more readable way of defining the type.
Also it seems that it's impossible to define more than one language on the same extension type (not 100% sure).
i have this tree structure:
repository/modules/module1
repository/modules/module2
repository/modules/module..
repository/apps/application1
repository/apps/application2
repository/apps/application..
where the applications are using some modules.
now, I'd like to put some resources inside a module (like a very colorfull icons inside a widget used by several applications) but.. something gets wrong.
inside the module CMakeLists.txt if I use only:
set(${MODULE_NAME}_RCS
colors.qrc
)
...
qt4_add_resources (${MODULE_NAME}_RHEADERS ${${MODULE_NAME}_RCS})
no qrc_colors.cxx are created anywhere. so I've tried to add:
ADD_EXECUTABLE (${MODULE_NAME}
${${MODULE_NAME}_RHEADERS}
)
but.. I get this weird error:
CMake Error at repo/modules/ColorModule/CMakeLists.txt:51 (ADD_EXECUTABLE):
add_executable cannot create target "ColorModule" because another
target with the same name already exists. The existing target is a static
library created in source directory
"repo/modules/ColorModule". See documentation for
policy CMP0002 for more details.
(I've changed the path of the error of course)
so.. don't know what to think because i'm new both to cmake and qt..
what can i try?
EDIT:
if I add the ${MODULE_NAME}_RHEADERS and ${MODULE_NAME}_RCS in the add_library command the qrc_colors.cxx is created BUT it is in repository/modules/module1/built and not copied in the application built directory...
There is at least two errors in your code.
1) It is usually not necessary to use ${MODULE_NAME} everywhere like that, just "MODULE_NAME". You can see that the difference is the raw string vs. variable. It is usually recommended to avoid double variable value dereference if possible.
2) More importantly, you seem to be setting ${MODULE_NAME} in more than one executable place, which is "ColorModule" according to the error output. You should have individual executable names for different binaries.
Also, the resource file focus is a bit of red herring in here. There are several other issues with your project.
You can cmake files as CmakeLists.txt instead of CMakeLists.txt which inherently causes issues on case sensitive systes as my Linux box.
You use Findfoo.cmake, and find_package(foo) for that matter, rather than the usual FindFoo.cmake convention alongside find_package(Foo).
Your FindFoo.cmake is quite odd, and you should probably be rewritten.
Most importantly, you should use config files rather than find modules.
Documentation and examples can be found at these places:
http://www.cmake.org/Wiki/CMake/Tutorials#CMake_Packages
https://projects.kde.org/projects/kde/kdeexamples/repository/revisions/master/show/buildsystem
When you would like use a find module, you need to have that at hand already. That will tell you what to look for, where things are, or if they are not anywhere where necessary. It is not something that you should write. You should just reuse existing ones for those projects that are not using cmake, and hence the find modules are added separately.
It is a bit like putting the treasure map just next to the treasure. Do you understand the irony? :) Once you find the map, you would automatically have the treasure as well. i.e. you would not look for it anymore.
I have a rather big library with a significant set of APIs that I need to expose. In fact, I'd like to expose the whole thing. There is a lot of namespacing going on, like:
FooLibrary.Bar
FooLibrary.Qux.Rumps
FooLibrary.Qux.Scrooge
..
Basically, what I would like to do is make sure that the user can access that whole namespace. I have had a whole bunch of trouble with this, and I'm totally new to closure, so I thought I'd ask for some input.
First, I need closurebuilder.py to send the full list of files to the closure compiler. This doesn't seem supported: --namespace Foo does not include Foo.Bar. --input only allows a single file, not a directory. Nor can I simply send my list of files to the closure compiler directly, because my code is also requiring things like "goog.assers", so I do need the resolver.
In fact, the only solution I can see is having a FooLibrary.ExposeAPI JS file that #require's everything. Surely that can't be right?
This is my main issue.
However, later the closure compiler, with ADVANCED_OPTIMIZATIONS on, will optimize all these names away. Now I can fix that by adding "#export" all over the place, which I am not happy about, but should work. I suppose it would also be valid to use an extern here. Or I could simply disable advanced optimizations.
What I can't do, apparently, is say "export FooLibrary.*". Wouldn't that make sense?
Finally, for working in source mode, I need to do goog.require() for every namespace I am using. This is merely an inconvenience, though I am mentioning because it sort of related to my trouble above. I would prefer to be able to do:
goog.requireRecursively('FooLibrary')
in order to pull all the child namespaces as well; thus, recreating with a single command the environment that I have when I am using the compiled version of my library.
I feel like I am possibly misunderstanding some things, or how Closure is supposed to be used. I'd be interested in looking at other Closure-based libraries to see how they solve this.
You are discovering that Closure-compiler is built more for the end consumer and not as much for the library author.
If you are exporting basically everything, then you would be better off with SIMPLE_OPTIMIZATIONS. I would still highly encourage you to maintain compatibility of your library with ADVANCED_OPTIMIZATIONS so that users can compile the library source with their project.
First, I need closurebuilder.py to send the full list of files to the closure compiler. ...
In fact, the only solution I can see is having a FooLibrary.ExposeAPI JS file that #require's everything. Surely that can't be right?
You would need to specify an --root of your source folder and specify the namespaces of the leaf nodes of your file dependency tree. You may have better luck with the now deprecated CalcDeps.py script. I still use it for some projects.
What I can't do, apparently, is say "export FooLibrary.*". Wouldn't that make sense?
You can't do that because it only makes sense based on the final usage. You as the library writer wish to export everything, but perhaps a consumer of your library wishes to include the source (uncompiled) version and have more dead code elimination. Library authors are stuck in a kind of middle ground between SIMPLE and ADVANCED optimization levels.
What I have done for this case is maintain a separate exports file for my namespace that exports everything. When compiling a standalone version of my library for distribution, the exports file is included in the compilation. However I can still include the library source (without the exports) into a project and get full dead code elimination. The work/payoff balance of this though must be weighed against just using SIMPLE_OPTIMIZATIONS for the standalone library.
My GeolocationMarker library has an example of this strategy.
I asked a question earlier today regarding using Perl to search in a CSS document. I have since refined my requirements a little bit, and have a better idea of what I am trying to do.
The document I am searching through is actually an .html doc with CSS as a style in the <head>, if that makes sense.
Basically, what I need to do though is find all the CSS elements that have a color or background color attribute, and record them. Here's my thought process.
open the file and set it as an array
read the array line-by-line until it comes to a "{"
make everything into a scalar variable or array until I get to the "}"
search the secondary variable or string for instances of "color" blah blah blah.
The issue I am having is finding a way to scour the document and turn everything between { and } into a variable of some sort. Any one have any ideas?
Cheers!
No matter what, I wouldn't recommend writing your own code from the ground up for this. You should use a parser. A quick search on CPAN suggests this family of modules. On the other hand, if your css is in an html file rather than a separate css file (shame on you), then you might end up needing a different type of parser.
Either way, it's generally not a good idea to try to hand-roll your own quasi-parser out of regular expressions. Use a proper parser, and leverage someone else's work.
On a slightly different tack, if you only want to extract some of the information from a file of any kind, then in many cases you don't want to put the whole file into an array first. (It can be memory intensive if the file is very large, and it's unnecessary.) It's easy to open the file and the process the items as you work through it line by line.
#!/usr/bin/env perl
use strict;
use warnings;
open my $fh, '<', 'file-of-interest'
or die "Couldn't open 'file-of-interest': $!";
my #saved_items;
while (my $line = <$fh>) {
# process $line
# push #saved_items, $something
}
# Do more fun stuff with #saved_items
You could use the CSS module, which is available on CPAN.
I think this is really just the same question that you asked previously, although you didn't mention as you did in a previous comment that you don't think you are allowed to use modules.
The CSS module already does this. You can look at the source to see how they do it. That's the same answer I gave you last time too.
There isn't really any magic or secret way that everyone is hiding from you. Most times, if the module you find on CPAN could be simpler, it would be. However, without any more information that constrains your problem, a general solution like SS](http://search.cpan.org/dist/CSS) is the way to go. Study that source or just lift it wholly into your script, although you might try some arguments to get some modules installed. If you could use the module, you might already be done and onto the next project. That's often a convincing argument. :)