Why can't I use OpenGL ES 3.0 in Qt? - qt

I set a QSurfaceFormat on my window, and this surface format has "3.0" set as its GL version number. The code:
static QSurfaceFormat createSurfaceFormat() {
QSurfaceFormat format;
format.setSamples(4);
format.setDepthBufferSize(24);
format.setStencilBufferSize(8);
format.setVersion(3, 0);
return format;
}
int main(int argc, char *argv[]) {
// ...
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QWindow* window = (QWindow*) engine.rootObjects().first();
window->setFormat(::createSurfaceFormat());
// ...
}
Also, in main() I enable OpenGL ES mode, like this:
QGuiApplication::setAttribute(Qt::AA_UseOpenGLES);
This means I'm requesting a GL ES 3.0 context.
The ANGLE docs say (in a table near the beginning) that GL ES 3.0 -> D3D 11 API translation support is implemented. And my system supports D3D 11 according to dxdiag.exe.
But when I launch my app, which contains this QML code...
Text {
text: OpenGLInfo.majorVersion + "." + OpenGLInfo.minorVersion
}
... I see "2.0" is displayed. Also, using the method I described here, I've determined that the maximal supported shading language version on my PC is "100" aka 1.0.
At the same time, from this Qt blog post I know that Qt supports GL ES 3.0 apps.
So why can't I use OpenGL ES 3.0 in Qt?

You need to set a QSurfaceFormat on a QWindow before the window itself is created (via create()). If you create top level windows via QML you have no control on when create() gets actually called, so a solution is changing the default surface format somwhere before you create your Q(Gui)Application:
int main(int argc, char **argv) {
// createSurfaceFormat() is the function you pasted above
QSurfaceFormat::setDefaultFormat(createSurfaceFormat());
QApplication app(argc, argv);
// etc.

Related

Bring up virtual input plugin from QML

Searching for an alternative to Qt's official VirtualKeyboard I came across this MockupVirtualKeyboard repository. It is based on QPlatformInputContext. I build and installed the plugin to Qt5.15.2/plugins/platforminputcontexts, but I dont know how to bring the Virtual Keyboard up.
What I would like to achieve, using QML, is:
TextInput{
text: ""
onFocusChanged: showVirtualInput()
}
If you want to use the keyboard then you must set the environment variable "QT_IM_MODULE" to be "mockup", and you can do that by placing the following line of code in the main.cpp:
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("mockup"));
#if QT_VERSION &lt QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
# ...
On the other hand, you must change:
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface" FILE "mockup.json")
to
Q_PLUGIN_METADATA(IID "org.qt-project.Qt.QPlatformInputContextFactoryInterface.5.1" FILE "mockup.json")
in the mockupplatforminputcontextplugin.h file, recompile and install the file so that it is compatible with Qt 5.15.2

QWebEngineView giving wrong geolocation coordinates

With the following code:
#include <QApplication>
#include <QWebEngineView>
#include <QWebEngineProfile>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
QWebEngineView w;
QObject::connect(w.page(), &QWebEnginePage::featurePermissionRequested, [&](const QUrl &securityOrigin, QWebEnginePage::Feature feature)
{
w.page()->setFeaturePermission(securityOrigin, feature, QWebEnginePage::PermissionGrantedByUser);
});
w.setUrl(QUrl("https://mycurrentlocation.net/"));
w.show();
return a.exec();
}
and a USB dongle connected to my 64bit Archlinux system (with geoclue2 installed and working), I don't get the correct geolocation coordinates (which I get on the same website with Google Chrome).
There are both in France but 200km apart.
Update 1:
A similar issue with the same coordinates seems to appear when centering on my position with a QML Map componenent.
Do I need to setup something in order for it to work ?
The issue is not Qt related.
/usr/lib/geoclue-2.0/demos/where-am-i
returns wrong coordinates.

Converting Text to Image (like PNG or JPEG)

I need help in writing my static text to image file without using "QApplication app(argc, argv);" in main(). My version of QT is 5.12.2.
Currently I'm able to do this with the below code:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QCoreApplication::addLibraryPath("./plugins");
QString imagePath(QStringLiteral("./images/output/testOutput1.png"));
QImage image(500, 400, QImage::Format_RGB888);
image.fill(Qt::red);
QPainter painter;
if (!painter.begin(&image))
return;
painter.setPen(QPen(Qt::black));
painter.setFont(QFont("Times", 12, QFont::Bold));
painter.drawText(image.rect(), Qt::AlignCenter, "writing text on image");
painter.end();
image.save(imagePath);
return 0;
}
I'm trying to get a similar type solution which does not uses "QApplication app(argc, argv);" in my code.
Currently if I remove the deceleration of "QApplication app(argc, argv);" my code crashes at "painter.drawText(...);".
The most you can do is to exchange the QApplication for a QGuiApplication (thus avoiding the useless dependency from the QtWidgets module).
Qt initializes most of its static/global stuff inside the bowels of QCoreApplication (for QtCore stuff)/QGuiApplication (for QtGui stuff)/QApplication (for QtWidgets stuff); each derives from the other, so if you have a QApplication you already have all the stuff from Gui and Core.
The font engine (and other paint-related stuff) is initialized inside the QGuiApplication constructor, as hinted in QFont documentation
Note that a QGuiApplication instance must exist before a QFont can be used.
so you are not going to paint without instantiating it (or a class derived from it).

How do I disable special handling of & on Qt button labels?

I have inherited a virtual keyboard system with an array of buttons, one for each key. The label for each button is a single QChar. When showing the "symbols" keyboard, the code uses an '&' QChar for a key label, but the key shows as blank. I'm sure Qt is processing the '&' as a shortcut key prefix. Similarly, the entered text is shown on another, longer, button label; this label, as well, handles '&' character as an accelerator. Entering "ABC&DEF" is shown as "ABCDEF" with the 'D' underlined.
I have tried building with QT_NO_SHORTCUT #defined, but that made no difference.
Does anyone know of an easy way to disable this special handling of '&'?
The answer is found in Qt doc. QAbstractButton::text:
If the text contains an ampersand character ('&'), a shortcut is automatically created for it. The character that follows the '&' will be used as the shortcut key. Any previous shortcut will be overwritten or cleared if no shortcut is defined by the text. See the QShortcut documentation for details. To display an actual ampersand, use '&&'.
(Emphasize by me.)
QPushButton is derived from QAbstractButton inheriting this behavior.
Sample testQPushButtonAmp.cc:
#include <QtWidgets>
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
QPushButton qBtn("Text with &&");
qBtn.show();
return app.exec();
}
testQPushButtonAmp.pro:
SOURCES = testQPushButtonAmp.cc
QT = widgets
Compiled and tested on cygwin64 on Windows 10:
$ qmake-qt5 testQPushButtonAmp.pro
$ make
$ ./testQPushButtonAmp
Qt Version: 5.9.4
Concerning how to disable this default behavior:
I had a look at woboq.org QAbstractButton::setText().
void QAbstractButton::setText(const QString &text)
{
Q_D(QAbstractButton);
if (d->text == text)
return;
d->text = text;
#ifndef QT_NO_SHORTCUT
QKeySequence newMnemonic = QKeySequence::mnemonic(text);
setShortcut(newMnemonic);
#endif
d->sizeHint = QSize();
update();
updateGeometry();
#ifndef QT_NO_ACCESSIBILITY
QAccessibleEvent event(this, QAccessible::NameChanged);
QAccessible::updateAccessibility(&event);
#endif
}
So, QT_NO_SHORTCUT disables to retrieve the shortcut out of text but it has to be defined when Qt library is built from source. Actually, I'm afraid even with disabled shortcuts, the single & will still become invisible in output.
I digged deeper in woboq.org and found some promising candidates e.g.:
qt_set_sequence_auto_menmonic()
Specifies whether mnemonics for menu items, labels, etc., should be honored or not. On Windows and X11, this feature is on by default; on macOS, it is off. When this feature is off (that is, when b is false), QKeySequence::mnemonic() always returns an empty string.
Note: This function is not declared in any of Qt's header files. To use it in your application, declare the function prototype before calling it.
and a sample in QProxyStyle
#include "textedit.h"
#include <QApplication>
#include <QProxyStyle>
class MyProxyStyle : public QProxyStyle
{
public:
int styleHint(StyleHint hint, const QStyleOption *option = 0,
const QWidget *widget = 0, QStyleHintReturn *returnData = 0) const override
{
if (hint == QStyle::SH_UnderlineShortcut)
return 0;
return QProxyStyle::styleHint(hint, option, widget, returnData);
}
};
int main(int argc, char **argv)
{
Q_INIT_RESOURCE(textedit);
QApplication a(argc, argv);
a.setStyle(new MyProxyStyle);
TextEdit mw;
mw.resize(700, 800);
mw.show();
//...
}
which I tried in my sample.
Finally, nothing of them achieved the desired effect, i.e. only "&&" was rendered as & but "&" never.
__

QDomElement::setTagName doesn't seem to work

The code
#include <QtCore>
#include <QtXml/QDomElement>
int main(int argc, char *argv[])
{
QCoreApplication app(argc, argv);
QDomElement* element = new QDomElement();
element->setTagName("feature");
qDebug() << element->tagName();
return app.exec();
}
prints simply "". However, as far as I can tell from the documentation it should print "feature". In fact
qDebug() << element->isNull();
prints true so something is not being set correctly. Does anyone know what I am doing wrong?
I'm using Qt 4.6.3 on openSUSE Linux 11.2.
You cannot use the default constructor. You need to use QDomDocument::createElement(const QString &tagName). The element needs to be part of a document. You cannot use it "standalone".
Here's what the documentation says for the QDomElement default constructor:
QDomElement::QDomElement ()
Constructs an empty element. Use the QDomDocument::createElement() function to construct elements with content.
By "empty" they mean null.

Resources