Where is my QML when I run app from Desktop? - c++

I have very simple QT Widgets app with QML. It looks like this:
Main ( no changes ):
#include "mainwindow.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
QML:
import QtQuick 2.0
import QtQuick.Controls 2.11
Item {
Button {
text: "Ok"
}
}
MainWindow.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
widget = new QQuickWidget(this);
widget->setSource((QUrl(QStringLiteral("qrc:/test.qml"))));
widget->move(10,10);
widget->resize(400,400);
}
MainWindow::~MainWindow()
{
delete ui;
}
When I run this app from QTCreator, eveything is ok ( I see Button "ok" ). When I run this application from my folder on Desktop I don't see a Button ( my app of course is running ).
My folder on desktop with qmlTest app:
test.qml is in my qrc

Related

How me get acces ui from another class?

I have a database in a separate widget class datbase.ui that I insert as tab in mainwindow.ui. I want that when initializing the connection in the class datbase.ui statusbar in mainwindow.ui to change depending.
datbase.cpp
void DatBase::on_pushButton_clicked()
{
QSqlDatabase ddbb = QSqlDatabase::addDatabase("QSQLITE");
ddbb.setDatabaseName(".../db/ddberdbsqlite");
if (ddbb.open()){
// It is necessary that this status is displayed in mainwindow.ui
// How to get access to gui mainwindow?
ui->statusBar->showMessage("Successful connection!");
}
else{
ui->statusBar->showMessage("Not Successful connection!");
}
}
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "datbase.h"
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setWindowTitle("Measurement DDEBR");
connect(ui->tabWidget, QTabWidget::currentChanged, this, MainWindow::showTabPageIndex);
DatBase *tabDatBase = new DatBase();
ui->tabWidget->insertTab(0, tabDatBase, "Data Base");
}
MainWindow::~MainWindow()
{
delete ui;
}

Opening child window after n seconds from formation of parent window in Qt C++

I have three windows Mainwindow,firstwindow and secondwindow.I have a pushbutton in mainwindow,When i clicked the push button it opens the firstwindow.Up to this part everything is ok.
What i need is , I need to open secondwindow automaticaly after 2sec of the formation of firstwindow
What is happening now is when i clicking the push button in mainwindow, secondwindow will appear first,and the first window will form only after execution of second window.
I am using qt5 with qtcreator
MainWindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_clickMeButton_clicked()
{
FirstWindow * dlg = new FirstWindow;
dlg->show();
}
FirstWindow.cpp
#include "firstwindow.h"
#include "ui_firstwindow.h"
FirstWindow::FirstWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::FirstWindow)
{
ui->setupUi(this);
connect(this,SIGNAL(winMessage()),this,SLOT(openNewWindow()));
emit winMessage();
}
FirstWindow::~FirstWindow()
{
delete ui;
}
void FirstWindow::openNewWindow()
{
dlg = new SecondWindow;
dlg->show();
}
SecondWindow.cpp
**
#include "secondwindow.h"
#include "ui_secondwindow.h"
SecondWindow::SecondWindow(QWidget *parent) :
QDialog(parent),
ui(new Ui::SecondWindow)
{
ui->setupUi(this);
}
SecondWindow::~SecondWindow()
{
delete ui;
}
**
My understading is you want something like this:
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QPushButton>
class FirstWindow : public QWidget
{
Q_OBJECT
public:
FirstWindow() : QWidget() { resize(100, 100); }
};
class SecondWindow : public QWidget
{
Q_OBJECT
public:
SecondWindow() : QWidget() { resize(100, 100); }
};
class MainWindow : public QPushButton
{
Q_OBJECT
public:
MainWindow(QWidget* parent = nullptr);
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include <QTimer>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QPushButton(parent)
{
setText("Click me");
connect(this, &MainWindow::clicked, this, [this] {
FirstWindow* first = new FirstWindow;
first->show();
QTimer::singleShot(2000, this, [] {
(new SecondWindow)->show();
});
});
}
If you prefer to separate the implementations, you can start the timer in the first window; the timer will give time to return to the event loop and actually show the first window.
#include <QTimer>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QPushButton(parent)
{
setText("Click me");
connect(this, &MainWindow::clicked, this, [] {
FirstWindow* first = new FirstWindow;
first->show();
});
}
FirstWindow::FirstWindow()
{
resize(100, 100);
QTimer::singleShot(2000, this, [] {
(new SecondWindow)->show();
});
}
or more precisely, you may wait for the actual show event:
#include <QTimer>
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent) : QPushButton(parent)
{
setText("Click me");
connect(this, &MainWindow::clicked, this, [] {
FirstWindow* first = new FirstWindow;
first->show();
});
}
void FirstWindow::showEvent(QShowEvent *)
{
QTimer::singleShot(2000, this, [] {
(new SecondWindow)->show();
});
}

Using a qml type as a QWindow in C++ code

I've created a MainWindow : public QMainWindow and a qtquick ui file (for a toolbox) in qtcreator. I want the toolbox to appear as a floating subwindow in mainwindow. I'm trying to use QMdiArea for that. A tutorial I've seen says that I need to add a window to the QMdiArea like this:
mdi->addSubWindow(win);
where win is a QWidget. How do I use the toolbox created with qml in my C++ code?
You can use QQuickWidget but remember that the root of the QML must be an Item or a class that inherits from the Item, it can not be Window or ApplicationWindow.
#include <QApplication>
#include <QMainWindow>
#include <QMdiArea>
#include <QQuickWidget>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QApplication app(argc, argv);
QMainWindow w;
QMdiArea *mdiarea = new QMdiArea;
w.setCentralWidget(mdiarea);
QQuickWidget *toolbar = new QQuickWidget(QUrl("qrc:/main.qml"));
toolbar->setResizeMode(QQuickWidget::SizeRootObjectToView);
mdiarea->addSubWindow(toolbar);
w.show();
return app.exec();
}
main.qml
import QtQuick 2.9
import QtQuick.Controls 2.4
Rectangle {
visible: true
width: 640
height: 480
color: "red"
Button{
text: "Stack Overflow"
anchors.centerIn: parent
}
}

Connecting Signal QML to C++ (Qt5)

I would like to change a the color of a rectangle when I click a button. They are both in the main.qml file. I'd like to send a signal to C++ backend to change the color of the rectangle. I can't seem to figure it out from the code given in the documentation
main.qml:
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Window 2.2
import QtQuick.Dialogs 1.2
ApplicationWindow {
title: qsTr("Hello World")
width: 640
height: 480
visible: true
id:root
signal mysignal()
Rectangle{
anchors.left: parent.left
anchors.top: parent.top
height : 100
width : 100
}
Button
{
id: mybutton
anchors.right:parent.right
anchors.top:parent.top
height: 30
width: 50
onClicked:root.mysignal()
}
}
main.cpp:
#include <QApplication>
#include <QQmlApplicationEngine>
#include<QtDebug>
#include <QQuickView>
class MyClass : public QObject
{
Q_OBJECT
public slots:
void cppSlot() {
qDebug() << "Called the C++ slot with message:";
}
};
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MyClass myClass;
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QPushButton *mybutton = engine.findChild("mybutton");
engine.connect(mybutton, SIGNAL(mySignal()),
&myClass, SLOT(cppSlot()));
return app.exec();
}
Any help would be appreciated!
QPushButton *mybutton = engine.findChild("mybutton");
First, QObject::findChild finds QObjects by object name, not id (which is local to a context anyhow). Hence in QML you need something like:
objectName: "mybutton"
Second, I think you need to perform that findChild not on the engine itself, but on its root objects as returned from QQmlApplicationEngine::rootObjects().
// assuming there IS a first child
engine.rootObjects().at(0)->findChild<QObject*>("myButton");
Third, a Button in QML is represented by a type that you don't have available in C++. So you can't just assign the result to a QPushButton *, but you need to stick with the generic QObject *.
I had to create a seperate class and header file and then connect it to the signal in main.cpp
main.cpp
#include <QApplication>
#include <QQmlApplicationEngine>
#include<QtDebug>
#include <QQuickView>
#include<QPushButton>
#include<myclass.h>
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
QObject *topLevel = engine.rootObjects().at(0);
QQuickWindow *window = qobject_cast<QQuickWindow *>(topLevel);
MyClass myClass;
QObject::connect(window,
SIGNAL(mysignal()),
&myClass,
SLOT(cppSlot())
);
return app.exec();
}
myclass.h
#ifndef MYCLASS
#define MYCLASS
#include <QObject>
#include <QDebug>
class MyClass : public QObject
{
Q_OBJECT
public slots:
void cppSlot();
};
#endif // MYCLASS
myclass.cpp
#include<myclass.h>
void MyClass::cppSlot(){
qDebug()<<"Trying";
}

How to change central widget from custom widget class?

I'm starting with Qt. Previously I did with Java Swing, where I accomplished this by Card Layout. I have MainWindow, Login Widget and Dashboard Widget.
MainWindow.cpp
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// set login screen on startup
QWidget *login = new Login(this);
setCentralWidget(login);
}
Login.cpp
#include "login.h"
#include "ui_login.h"
Login::Login(QWidget *parent) :
QWidget(parent),
ui(new Ui::Login)
{
ui->setupUi(this);
}
Login::~Login()
{
delete ui;
}
void Login::on_loginButton_clicked()
{
// some logic
// here I want to create Dashboard widget in central widget
// but method setCentralWidget() can't be called from here
}
You want to use signals and slots to communicate between the windows. QDialog provides three important signals in particular: accepted(), rejected(), finished(int). So you'll want to do something like this:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
// set login screen on startup
QWidget *login = new Login(this);
connect(login, SIGNAL(finished(int)), this, SLOT(loginFinished(int)));
setCentralWidget(login);
}
MainWindow::loginFinished(int reason)
{
Login *login = qobject_cast<Login*>(sender());
if (!login) {
qDebug() << "something bad happened!";
return;
}
login->deleteLater();
setCentralWidget(someOtherWidget);
}