Arbitrary Inspection of Qt Stylesheet - c++

I have several Qt stylesheets that look something like this:
MyClass
{
my_color: #abcdef;
}
However, I recently moved MyClass into a new namespace, ns, which means that its corresponding qss classname is now "ns--MyClass", not just "MyClass". As a result, all my stylesheets are now invalid. Unfortunately, they aren't all under my control, so I cannot edit them manually.
So my question is: how can I configure ns::MyClass to use all the same style settings of MyClass?
Obviously, Qt has to parse the style sheet at some point. So if I could access the parsed style sheet and extract just the portions that affect MyClass, I should be able to add those portions into ns::MyClass via setStyle() or setStyleSheet(). But I cannot find a way to do this.
I am targeting Qt 4.8.

You'll need to patch Qt to add two methods to QApplication:
void setClassSubstitutions(const QMap<QString, QString> &);
QMap<QString, QString> classSubstitutions() const;
The substitutions would be held in the application's PIMPL, and you'd need to have the stylesheet mechanism use them. The entirety of the patch needed for Qt would be probably two dozen lines (or so I hope).

Related

How to redefine the way Qt Creator creates getter and setter functions?

Is it possible to edit how QtCreator generates the signatures for "getter and setter" functions from the refactor context menu? Specifically, it gives me this right now when I define getter/setter for "m_camera":
std::shared_ptr<CameraGrabber> camera() const;
void setCamera(const std::shared_ptr<CameraGrabber>& camera);
private:
std::shared_ptr<CameraGrabber> m_camera;
When in fact I want to get something like this instead:
auto camera() const -> std::shared_ptr<CameraGrabber> ;
void setCamera(std::shared_ptr<CameraGrabber> camera);
private:
std::shared_ptr<CameraGrabber> m_camera;
This is with QtCreator version 4.0.3; perhaps there is some custom plugin or template definition file that can be used to control how get/set functions are declared?
related:
qtcreator customize getters and setters
How to add short-key for "Add Definition in class.cpp" in Qt Creator
This is not possible at the moment, neither with qtcreator itself nor with any plugins that I'm aware of.
I suggest you vote for the corresponding feature request: https://bugreports.qt.io/browse/QTCREATORBUG-12678 .
The easiest way would be for you to make your own build of Qt Creator (this can be done from within Qt Creator!), and modify the plugin that does the refactoring to your taste. It should be a minimal change I think.

Qt: Generate ui_ classes using uic, load dynamically by class name

Is it possible to load an .ui class generated by uic, dynamically by class name? I need to decide which UI class to load dynamically. I do not have that information at compile time. I do not want to use QUiLoader. Instead, I want to combine the direct approach here with QMetaType object instantiation by string.
I.e.
add the UI file to FORMS in project file,
declare the UI classes for QMetaType usage Q_DECLARE_METATYPE(Ui::planar_break) or Q_DECLARE_METATYPE(Ui_planar_break)
then form a string class name dynamically depending on user action: "Ui::planar_break" or "Ui_planar_break"
and invoke the below function to get the UI widget pointer for usage?
QWidget* initiateClassByName(QString name){
int id = QMetaType::type(name.toLatin1());
QWidget* widget=nullptr;
if (id != QMetaType::UnknownType) {
widget=static_cast< QWidget* > (QMetaType::create(id));
//QMetaType::destroy(id, myClassPtr);
//myClassPtr = 0;
}
return widget;
}
I am trying to increase the performance, compared to loading a dozen or so UI files (stored in Qt resource files) dynamically every time a specific dialog is instantiated. When I do this I seem to get a QMetaType::UnknownType every time. Ideas? Thanks.
(Hm, not sure why my function wasn't showing as code block here, until I made it a quotation.)
uic creates C++ code. If you really want to dynamically create a widget/dialog out of an xml file at runtime, you need to use the Qt Ui Tools. The class QUiLoader might be what you are looking for. If you do this, you can query the created QWidget through QWidget::findChild You can interact with the UI items through QObject::findChild(), provided you give your widgets distinct and meaningful object names.
Essentially, based on discussion had in #qt irc channel on Freenode I think what I am asking is actually not feasible.
My understanding is that even if I could get the C++ headers compiled and the classes registered using perhaps also qRegisterMetaType(), and perhaps even get them instantiated using QMetaType, to actually get the UI built I would have to call setupUi() on the instance.
Since UI files do not implement a common interface that includes setupUi, and I don't know compile-time which class I am instantiating, calling setupUi becomes impossible.

Qt Translations: What context should I use in the ts file for standard buttons like OK, Save, Cancel?

I don't want to use Qt's qm file. I want to generate my own qm files for different languages. I tried using context like QDialogButtonBox, QDialog, but still the button text is still untranslated. I have used code like:-
static const char* const messages[] = {
QT_TRANSLATE_NOOP("QDialogButtonBox", "OK"),
QT_TRANSLATE_NOOP("QDialogButtonBox", "Cancel"),
};
First, add this:
QT_TRANSLATE_NOOP("QDialogButtonBox", "&OK"),
QT_TRANSLATE_NOOP("QDialogButtonBox", "&Cancel"),
Second, go to qt-src/translations/qt_<lang>.ts, open QDialogButtonBox section and add everything from there, you are using.

How do I cast QML items to corresponding C++ Item in Qt Quick

My question is best clarified by an example. I have QML with a Text{} item. In C++ I can get to this item and I have no problem using qobject_cast to turn anything into a QQuickItem*. But how do I turn it into the closest corresponding item so that I can call more specific methods directly like setText() the same way I might call setWidth()? I realize I can use the generic setProperty() method but I'm after the compile time checking that casting offers.
I'm after a more general answer for finding the correspondence between QML and their C++ classes, so that I can find out how to do this for Rectangles, MenuBars etc. I can't seem to find this in the docs. For those that prefer code examples:
auto text_object = app_item->findChild<QObject*>("myTextArea");
text_object->setProperty("text","New Text set from Code"); //THIS WORKS BUT...
auto text_qitem = qobject_cast<QQuickItem*>(text_object);
text_qitem->setWidth(128);
auto text_quick_text = qobject_cast<WHATGOESHERE???*>(text_object);
text_quick_text->setText("new Text for qml item"); //I WANT TO DO THIS
Q: but I'm after the compile time checking that casting offers.
qobject_cast does not offer any compilation-time checking. It is all runtime and dynamic, thus this request is not plausible. The context property is fine, or you could also get the class name with QMetaObject. Then, you could build a static LUT, but the effort may not be worth it overall...
All QML properties and methods are exposed to the meta-object system and can be called from C++ using Object::setProperty and QMetaObject::invokeMethod() respectively. invokeMethod parameters and return values passed from QML are always translated into QVariant values in C++:
QString msg("That's it");
auto text_object = app_item->findChild<QObject*>("myTextArea");
if (text_object)
QMetaObject::invokeMethod(text_object, "append", Q_ARG(QString, msg));

qt/c++ naming of variables dynamically

I am in the process of developing a html editor in Qt for one of my university assignments, and i am having a problem regarding naming of some variables.
the problem is this:
when the user decides to load their "project" the program iterates through the folder and finds how many .html files are in there, it then creates tabs for them to be displayed in.
I have a custom QTextEdit which has a customer completer and syntax highlighting etc. the problem i am having at the moment is how to create them depending on the number needed.
i create a QStringList of file names:
QStringList m_files;
m_files = aDialog.m_loadDirectory->entryList(QStringList("*.html"),QDir::Files|QDir::NoSymLinks);
then i iterate through each one of the list:
for(int i=0; i<m_files.count();i++)
{
}
and for each one i need to create a new custom QtextEdit
TextEdit *name = new TextEdit;
then add to the tab
tabs->addTab(name,"someTitle");
but as each TextEdit needs to be different for each tab (i think this is correct) i need a different Variable name for each one.
i thought about creating a list/array of TextEdit objects but as i dont know how many i need to use, i could end up easily with too many (wasted memory) or not enough..
any ideas on how i can get around this?
one thought..
would it be possible to create a TextEdit object before the loop
then make a copy of that object in the loop and add the copied object to the tab? (still variable naming problem...)
thanks
but as each TextEdit needs to be different for each tab (I think this is correct)
Yes, you need a different TextEdit in each tab.
I need a different Variable name for each one.
No, you don't need a different variable name for each one. You need different objects, but variable names don't have much to do with that.
A simple:
for (...) {
TextEdit *te = new TextEdit(...);
// set up that text edit in whatever way you need
tabs->addWidget(te, "foo");
}
does exactly what you want. The variable name te is completely irrelevant (it won't even appear in the executable outside of debugging symbols). Each time through the loop, you'll be working on a separate TextEdit instance.
If you need to refer to that TextEdit by name at runtime, you can keep all your widgets in a collection, a QMap for instance.
QMap<QString, QWidget*> all_editors;
...
for (...) {
TextEdit *te = ...;
all_editors[filename] = te;
...
}
You have discarded quickly the only viable solution : put your text edits in a collection. The textedit have to be created with new, so the collection itself will not waste space.
You can use a QPair<QTabWidget*, QTextEdit*> for simplest cases. For more complicated cases create a custom widget, and just make a list of those.
Copying a QObject is a really bad idea. I think the copy constructor is private so you will not even be able to do that