I try to add some QML object to my QGraphcisScene but they don't display in the scene. Here is the code.
QList<QObject*> dataList;
dataList.append(new DataObject("Item 1", "red"));
dataList.append(new DataObject("Item 2", "green"));
QDeclarativeEngine engine ;
QDeclarativeContext *context = engine.rootContext();
context->setContextProperty("myModel", QVariant::fromValue(dataList));
QUrl url("qrc:view.qml") ;
QDeclarativeComponent component(&engine,url ) ;
QDeclarativeItem *item = qobject_cast <QDeclarativeItem *>(component.create());
item->setFlag(QGraphicsItem::ItemHasNoContents, false);
myScene->addItem(item);
And here is my qml file:
ListView {
width: 100; height: 100
model: myModel
delegate: Rectangle {
height: 25
width: 100
color: model.modelData.color
Text { text: name }
}
}
You can add a QML in a QDeclarativeView to your scene using addWidget:
QDeclarativeView view;
view.setSource( QUrl("qrc:view.qml"));
view.setStyleSheet("background-color:transparent");
QGraphicsProxyWidget * item = myScene->addWidget((QWidget *)view);
For QtQuick 2.0 you can embed QQuickView in a widget using createWindowContainer :
QQuickView *view = new QQuickView();
...
QWidget *container = QWidget::createWindowContainer(view);
container->setMinimumSize(...);
container->setMaximumSize(...);
container->setFocusPolicy(Qt::TabFocus);
QGraphicsProxyWidget * item = myScene->addWidget((QWidget *)container);
Related
I have a QML ListView and I want to access to the delegate children in c++
main.qml
ApplicationWindow {
objectName: "wnd1"
ListView {
objectName: "mediaPlayerListView"
model: provider.mediaPlayerItems
delegate: MediaPlayerDelegate
}
}
MediaPlayerDelegate.qml
Row {
objectName: "mainRow"
VideoOutput {
objectName: "videoOutput" + modelData.id
}
Here is the c++ code I've tried
QString currentId = "1";
QQuickWindow *mainWindow = _qmlAppEngine->rootObjects()[0]->findChild<QQuickWindow *>("wnd1");
QObject *mediaPlayerListView = mainWindow->findChild<QObject *>("mediaPlayerListView");
QObject *mediaPlayerListViewDelegate = mediaPlayerListView->property("delegate").value<QObject *>();
I want to be able to get in cpp the videoOutput, doing something like this
QObject *videoOutput = mediaPlayerListViewDelegate->findChild<QObject *>("videoOutput" + currentId)
But I can't access further than the delegate, it has no children.
I am trying to fit tool bar from QDockWidget and view from QGraphicsView in a same window.
But it is not getting fit properly. I am expecting view window should start from below the tool bar icons. And view should occupy the whole window.
QWidget* p = new QWidget();
QBoxLayout* toolLayout = new QBoxLayout(QBoxLayout::LeftToRight,p);
toolLayout->setContentsMargins(0, 0, 0, 0);
auto toolbar = new QToolBar;
toolbar->setIconSize(QSize(45,45));
toolLayout->addWidget(toolbar,0,Qt::AlignTop);
const QIcon newIcon = QIcon::fromTheme("document-new", QIcon(":/img/c.png"));
QAction* zoomIn = new QAction(newIcon, tr("&Zoom In"), this);
const QIcon newIcon1 = QIcon::fromTheme("document-new", QIcon(":/img/c1.png"));
QAction* zoomOut = new QAction(newIcon1, tr("&Zoom Out"), this);
const QIcon newIcon2 = QIcon::fromTheme("document-new", QIcon(":/img/c2.png"));
QAction* fitIn = new QAction(newIcon2, tr("&Fit In"), this);
toolbar->addAction(zoomIn);
toolbar->addAction(zoomOut);
toolbar->addAction(fitIn);
QObject::connect(zoomIn, SIGNAL(triggered()), this, SLOT(zoomIn()));
scene = new QGraphicsScene(this);
view = new QGraphicsView(this);
view->setScene(scene);
toolLayout->addWidget(view);
p->setLayout(toolLayout);
QLabel *label = new QLabel("myView");
label->setStyleSheet(
"QLabel { padding-left: 5px;font-size: 5px;"
}");
setWidget(p);
Where am I wrong ?
I am trying to make a panel that shows some data, that gets added when I press a button. I will explain it trough these images:
this would be the initial state of the app, a window with a QGraphicsView
if I click "Help" it should display a window above it that never goes out of focus
I looked into using QDockWidget, but that just creates a panel next to it, that that's not what I Want. If anyone knows how to do this, I would be very grateful, thanks.
You can set children widgets in your QGraphicsView and consider it like a regular QWidget:
QApplication app(argc, argv);
QGraphicsScene* scene = new QGraphicsScene(0, 0, 1000, 1000);
QGraphicsView* view = new QGraphicsView(scene);
view->show();
QPushButton* button = new QPushButton("Show label");
QLabel* label = new QLabel("Foobar");
QVBoxLayout* layout = new QVBoxLayout(view);
layout->setAlignment(Qt::AlignRight | Qt::AlignTop);
layout->addWidget(button);
layout->addWidget(label);
label->hide();
QObject::connect(button, &QPushButton::clicked, label, &QLabel::show);
return app.exec();
The label will be visible in the QGraphicsView when you click on the button.
You can also embed a widget in your scene with QGraphicsProxyWidget class:
QApplication app(argc, argv);
QGraphicsScene* scene = new QGraphicsScene(0, 0, 1000, 1000);
scene->addItem(new QGraphicsRectItem(500, 500, 50, 50));
QGraphicsView* view = new QGraphicsView(scene);
view->show();
QWidget* w = new QWidget();
QGraphicsProxyWidget* proxy = new QGraphicsProxyWidget();
QPushButton* button = new QPushButton("Show label");
QLabel* label = new QLabel("Foobar");
QVBoxLayout* layout = new QVBoxLayout(w);
layout->addWidget(button);
layout->addWidget(label);
layout->setAlignment(Qt::AlignRight | Qt::AlignTop);
label->hide();
QObject::connect(button, &QPushButton::clicked, label, &QLabel::show);
proxy->setWidget(w);
scene->addItem(proxy);
return app.exec();
So I could change the property of a certain QML object via C++ code, but I couldn't see the result on screen.
I have an item repeated 64 times, and I want a certain image to be displayed only for the 32nd item (from C++) so I used invokeMethod to access the object via C++ then I used setProperty to change the visibility, if I view it with qDebug the property "visible" did change, but I notice no difference on the screen I still cannot see the image, but if I change the visibility from qml, I can see it.
This is the C++ code:
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQuickView view;
view.setSource(QUrl("qrc:///main.qml"));
view.show();
QQuickItem* child;
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///Board.qml")));
QObject *rootObject = engine.rootObjects().first();
QQuickItem *qmlObject = rootObject->findChild<QQuickItem*>("grid")->findChild<QQuickItem*>("repeter");
QMetaObject::invokeMethod(qmlObject,"itemAt",Qt::DirectConnection, Q_RETURN_ARG (QQuickItem*,child), Q_ARG(int,32));
child=child->findChild<QQuickItem*>("pleaseWork");
qDebug() << child->property("visible");
child->setProperty("visible","true");
qDebug() << child->property("visible");
return app.exec();
}
I used qDebug to verify the property changed
This is the QML code :
Item
{
id: root
width: 8*45
height: 8*45
Grid
{
id: grid
objectName: "grid"
rows: 8
Repeater
{
objectName: "repeter"
model: 64
Image
{
objectName: "test"
width: 45; height: 45
source: "images/dark_square.png"
Image
{
id: isit
objectName: "pleaseWork"
visible: false
source: "images/avail_dark.png"
}
}
}
}
}
QQuickView and QQmlApplicationEngine are alternative ways to load and show QML views. What you are loading into QQmlApplicationEngine has nothing to do with the visible output of QQuickView.
In order to get things running, you need to change the top element of the QML file from Item to Window and show it on screen:
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:///Board.qml")));
// end of your code
QObject *rootObject = engine.rootObjects().first();
QQuickWindow *window = qobject_cast<QQuickWindow *>(rootObject);
if (!window) {
qDebug() << "Error: Your root item has to be a window.";
return -1;
}
window->show();
// continue with your code
QQuickItem *qmlObject = rootObject->findChild<QQuickItem*>("grid")->findChild<QQuickItem*>("repeter");
I have tried with
widget->setProperty("text1Text", QVariant("After..."));
in my C++,
and
Button
{
property alias text1Text: text1.text
Text
{
id: text1
text: "Initial"
}
}
in qml.
widget is a QQuickWidget object. What am I doing wrong?
See Interacting with QML Objects from C++.
If you are using QQmlEngine:
// Using QQmlComponent
QQmlApplicationEngine engine;
...
QObject * root = engine.rootObjects().first();
If you are using QQuickView:
QQuickView view;
...
QObject * root = view.rootObject();
Getting text1:
// Update Qml file
Text
{
id: text1
text: "Initial"
objectName: id
}
// Find text1 in c++
QObject * o1 = root->findChild<QObject *>(QStringLiteral("text1"));
QQuickItem *text1 = qobject_cast<QQuickItem*>(o1);
// Set property
text1->setProperty("text", QVariant());