I have a basic qml application QWindow that already defines the property flags. I would like to change/update the property flags from main.cpp so that it is not frameless. I know I can do it directly in QML but I'd like to change it dynamically without re-compiling. I have found a number of examples but none show how to do this after using QQmlApplicationEngine::load() method. I posted my code below and I am able to see the current flags decimal value 2048 or hex value 0x800. According to documentation the hex value of 0x800 refers to Qt::FramelessWindowHint which is the current setting. I have tried to modify the flags property but the window doesn't update.
// Main.qml
import QtQuick 2.9
import QtQuick.Window 2.2
Window {
id: window
objectName: "window"
...
flags: Qt.FramelessWindowHint
...
}
// main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/");
QObject::connect(&engine, &QQmlApplicationEngine::quit, &app,
&QGuiApplication::quit);
const QUrl url(QStringLiteral("qrc:/Main.qml"));
QObject::connect(
&engine, &QQmlApplicationEngine::objectCreated, &app,
[url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl) QCoreApplication::exit(-1);
QVariant obj2 = obj->property("flags");
if (obj2.isValid()) {
Qt::WindowFlags flags = qvariant_cast<Qt::WindowFlags>(obj2);
flags &= ~Qt::FramelessWindowHint;
auto *tmp = dynamic_cast<QWindow*>(obj);
tmp->setFlags(flags);
tmp->show();
}
},
Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
you have obj and if you want that main.qml change you can easily add property to this:
obj->setProperty("flags", Qt::FramelessWindowHint);
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl)
{
if (!obj && (url == objUrl))
{
QCoreApplication::exit(-1);
}
obj->setProperty("flags", Qt::FramelessWindowHint);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
Edited :
Related
I want to know the line number in editText where the cursor is. How do I get that?
I checked the documentation, and there's no
ps:Is the textedit QML,not QTextEdit
You have to use textDocument and cursorPosition properties in c++:
main.cpp
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
#include <QQuickTextDocument>
#include <QTextBlock>
class Helper: public QObject{
Q_OBJECT
public:
Q_INVOKABLE int currentLineNumber(QQuickTextDocument *textDocument, int cursorPosition){
if(QTextDocument * td = textDocument->textDocument()){
QTextBlock tb = td->findBlock(cursorPosition);
return tb.blockNumber();
}
return -1;
}
};
#include "main.moc"
int main(int argc, char *argv[])
{
#if QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
#endif
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
Helper helper;
engine.rootContext()->setContextProperty("helper", &helper);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
main.qml
import QtQuick 2.15
import QtQuick.Window 2.15
Window {
width: 640
height: 480
visible: true
TextEdit{
id: textEdit
anchors.fill: parent
onCursorPositionChanged: function(){
let line = helper.currentLineNumber(textEdit.textDocument, textEdit.cursorPosition);
console.log(line);
}
}
}
I want to get the id of the window by name using c++ or qml and record the specific screen using this id in ffmpeg.
ffmpeg -f x11grab -wid 0x6200012 -s 1920x1052 -r 30 -i :0.0+0,0
How can I do this?
it's not necessary to be the id, can be the offset-x and offset-y, I just want to record the window in any position.
I do not see that x11grab can record some screen by id as this answer indicates so as that answer points out one option is to use GStreamer:
gst-launch-1.0 ximagesrc xid=0x04000007 ! videoconvert ! autovideosink
How do I get the window id in Qt?
If QQmlApplicationEngine is used with Window or ApplicationWindow:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QWindow>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url, &engine](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
if(QWindow *w = qobject_cast<QWindow *>(engine.rootObjects().first())){
qDebug() << w->winId();
}
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
With QQuickView
#include <QGuiApplication>
#include <QQuickView>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQuickView view;
const QUrl url(QStringLiteral("qrc:/main.qml"));
view.setSource(url);
view.show();
qDebug() << view.winId();
return app.exec();
}
Qt Widgets:
#include "mainwindow.h"
#include <QApplication>
#include <QDebug>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
qDebug() << w.winId();
return a.exec();
}
Or in general you should access the QWindow and get the window id:
for(QWindow *w : QGuiApplication::allWindows()){
qDebug() << w->winId();
}
I found out the following:
ffmpeg -y -s 800x600 -f x11grab -window_id 0x3200008 -framerate 30 -i :11.0+0,0 -c:v libx264 -preset ultrafast -crf 40 output_select_window.mp4
Very important explanation:
-window_id = 'xwininfo' shows window_id if you select a window
-i :11.0+0,0 = 11 means and from in shell with `$echo $Display`.
A QVariant I took from C++ contains a QJsonDocument, and I want to convert it to a js object, but I only found the use of QJsonDocument in C++. I couldn't find how to use QJsonDocument in qml.
For Example:
Qml:
function qmlUpdateObject( Object ){
console.log(Object);
}
// console content: qml: QVariant(QJsonDocument, QJsonDocument({"appDesc":{"description":"SomeDescription","message":"SomeMessage"},"appName":{"description":"Home","imp":["awesome","best","good"],"message":"Welcome"}}))
// I want to get a js object: {"appDesc":{"description":"SomeDescription","message":"SomeMessage"},"appName":{"description":"Home","imp":["awesome","best","good"],"message":"Welcome"}}
C++:
QObject::connect( this, SIGNAL( updateData(QVariant)),
viewItem, SLOT( qmlUpdateObject(QVariant)) );
void Controller::setData(QString name)
{
QFile file("data.json");
QJsonDocument d = QJsonDocument::fromJson(file.readAll());
QByteArray dataJson = d.toJson(QJsonDocument::Compact);
emit updateData(dataJson);
}
UPDATE
Add this line and pass back, qml can successfully parse:
QByteArray dataJson = d.toJson(QJsonDocument::Compact);
There is no direct QJsonDocument conversion to a js object. One possible solution is to convert the QJsonDocument to QByteArray and export it to QML, and in QML do parse using JSON.parse():
C++
QByteArray dataJson = doc.toJson(QJsonDocument::Compact);
// send dataJson to QML
QML
var json = JSON.parse(dataJson)
Note:
It seems that the OP does not know the good practice of not accessing QML objects from C++ but must create a QObject and export it to QML.
The example provided by the OP is not necessary to use QJsonDocument since JSON.parse() does the same as QJsonDocument d = QJsonDocument::fromJson(file.readAll());.
#include <QFile>
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
class Controller: public QObject{
Q_OBJECT
public:
void setData(const QString & filename){
QFile file(filename);
if(file.open(QIODevice::ReadOnly))
Q_EMIT updateData(file.readAll());
}
Q_SIGNALS:
void updateData(const QByteArray & data);
};
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
Controller controller;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("controller", &controller);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
controller.setData("data.json");
return app.exec();
}
#include "main.moc"
import QtQuick 2.14
import QtQuick.Window 2.14
Window {
visible: true
width: 640
height: 480
title: qsTr("Hello World")
function qmlUpdateObject( data ){
var obj = JSON.parse(data)
console.log(obj);
}
Connections{
target: controller
onUpdateData: qmlUpdateObject(data)
}
}
I'm learning the QT basic, starting the new project QT Quick APP Empty. Running for first time, the app run. Modifying the code:
import QtQuick 2.12
import QtQuick.Window 2.12
import QtQuick.VirtualKeyboard 2.4
Window { x: 100; y: 100; width: 100; height: 100; visible: true }
Output response:
17:34:02: Starting /home/PC/Documents/Projects/QT_APP/build-FirstAPP-Desktop_Qt_5_12_2_GCC_64bit-Release/FirstAPP ...
Nothing besides that happens. Am I forgetting anything?
Updating
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
qputenv("QT_IM_MODULE", QByteArray("qtvirtualkeyboard"));
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
Worked, after I Clean and build project again!
How do you call for example QFile::exists(path) inside a QML file in Qt 5.5?
MyFile.qml
import QtQuick 2.5
// These are some various things I've tried, with the error message they
// give related to the row where I call QFile::exists()
#include <QFile> // Expected token `{'
import QtQml 2.5 // Expected token `;'
import io.qt // Expected token `;'
import io.qt.QFile // Expected token `;'
Item {
id: root
property string imageSource
Image {
id: test
source: fileOrFallback(root.imageSource)
}
function fileOrFallback (source) {
return QFile::exists(source)
? preprocessor.getFilePath(source)
: theme.example + 'placeholder.png'
}
}
I've seen some examples on how to import your custom Qt functions, but how do you call built-in Qt functions in QML?
You cannot directly import a C ++ function, in these cases the approach is to create a QObject that exposes the method through a Q_INVOKABLE:
backend.h
#ifndef BACKEND_H
#define BACKEND_H
#include <QObject>
class Backend : public QObject
{
Q_OBJECT
public:
using QObject::QObject;
Q_INVOKABLE bool exists(const QString &fileName);
};
#endif // BACKEND_H
backend.cpp
#include "backend.h"
#include <QFile>
bool Backend::exists(const QString &fileName){
return QFile::exists(fileName);
}
main.cpp
#include "backend.h"
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
Backend backend;
QQmlApplicationEngine engine;
engine.rootContext()->setContextProperty("backend", &backend);
const QUrl url(QStringLiteral("qrc:/main.qml"));
QObject::connect(&engine, &QQmlApplicationEngine::objectCreated,
&app, [url](QObject *obj, const QUrl &objUrl) {
if (!obj && url == objUrl)
QCoreApplication::exit(-1);
}, Qt::QueuedConnection);
engine.load(url);
return app.exec();
}
*.qml
// ...
function fileOrFallback (source) {
return backend.exists(source)
? preprocessor.getFilePath(source)
: theme.example + 'placeholder.png'
}
// ...