How to get your personalized library widget in QT design window? - c++

I am a newbie to QT.
My goal is to access my personalized widget(created in my DLL) from the Design window of application in QT.
I was able to create the DLL successfully and call it from my application.
Kindly guide me as to how to access the DLL widget which I created in the design window along with other library QML types.
Thanks in advance,
Sam
Please find my files below :
myCppLib.h
#ifndef MYCPPLIB_H
#define MYCPPLIB_H
#include "mycpplib_global.h"
#include <QDebug>
#include <QWidget>
class MYCPPLIBSHARED_EXPORT MyCppLib : public QWidget
{
private:
Q_OBJECT
public:
MyCppLib();
void Test();
//void resize(int, int);
//void show();
};
#endif // MYCPPLIB_H
Application
main.cpp
#include <QGuiApplication>
#include <QApplication>
#include <QQmlApplicationEngine>
#include <mycpplib.h>
int main(int argc, char *argv[])
{
//QGuiApplication app(argc, argv);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
MyCppLib testLib;
//testLib.resize(200,200);
testLib.setProperty("height", 250);
testLib.setProperty("width", 250);
testLib.Test();
testLib.show();
return app.exec();
}

Related

QT QML Translation retranslate

I'm running QT 5.10.1 on Windows, the app is only made in QML. I'm trying to use the new retranslate() to change language during runtime. The current code is working fine with texts that use the getEmptyString() appended to it. But the rest of the text within qsTr() does not. TranslationHandler.cpp is empty and I haven't cleaned up the includes.
So I'm able to set a language from the QML using the context property. Also I checked so the engine is the same instance. Any ideas why the retranslate function is not working?
Thanks for the help!
main.cpp :
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QTranslator>
#include <QtGui>
#include <QQmlContext>
#include <QDebug>
#include <QQmlEngine>
#include "translationhandler.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
TranslationHandler transHndl(&engine);
engine.rootContext()->setContextProperty("translateHandler", &transHndl);
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
TranslationHandler.h :
#ifndef TRANSLATIONHANDLER_H
#define TRANSLATIONHANDLER_H
#include <QTranslator>
#include <QString>
#include <QGuiApplication>
#include <QObject>
#include <QDebug>
#include <QQmlEngine>
class TranslationHandler : public QObject
{
Q_OBJECT
Q_PROPERTY(QString emptyString READ getEmptyString NOTIFY languageChanged)
public:
explicit TranslationHandler(QQmlEngine *engine)
{
m_translator1 = new QTranslator(this);
m_currentLanguage = "en";
m_engine = engine;
}
QString getEmptyString()
{
return "";
}
Q_INVOKABLE QString getCurrentLanguage()
{
return m_currentLanguage;
}
Q_INVOKABLE void selectLanguage(QString language)
{
if(language == QString("jp"))
{
m_currentLanguage = language;
m_translator1->load(":/translation/qml_jp.qm");
qGuiApp->installTranslator(m_translator1);
m_engine->retranslate();
}
if(language == QString("en"))
{
m_currentLanguage = language;
qGuiApp->removeTranslator(m_translator1);
m_engine->retranslate();
}
emit languageChanged();
}
signals:
void languageChanged();
private:
QTranslator *m_translator1;
QString m_currentLanguage;
QQmlEngine *m_engine;
public slots:
};
#endif // TRANSLATIONHANDLER_H
This was confirmed as a bug and will be fixed in version 5.12. If you want to compile it yourself please check the bug report
https://bugreports.qt.io/browse/QTBUG-68350

Enable resizing on QWidget

I want a resize feature in a QWidget using Qt, like the one shown in the image below.
I have used following tried following ways:
using QSizeGrip, setSizeGripEnabled
For completeness I'm showing two examples: with and without the Qt Designer.
Example using Qt Designer
Check the sizeGripEnabled property:
Preview from within the Qt Designer (Form > Preview...):
Minimal application to show the dialog:
#include <QtWidgets/QApplication>
#include <QDialog>
#include "ui_DialogButtonBottom.h"
class Dialog : public QDialog {
public:
Dialog(QWidget* parent = nullptr) :
QDialog(parent) {
ui.setupUi(this);
}
private:
Ui::Dialog ui;
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Dialog dlg;
return dlg.exec();
}
Resut
Without Qt Designer
#include <QtWidgets/QApplication>
#include <QDialog>
class Dialog : public QDialog {
public:
Dialog(QWidget* parent = nullptr) :
QDialog(parent) {
setWindowTitle("Example");
setSizeGripEnabled(true);
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Dialog dlg;
return dlg.exec();
}
Result
Update to include Frameless mode
Adding the Frameless windows hint doesn't change anything: it works correctly. Obviously, there is no frame so resize/move methods provided by the windows manager are not available.
#include <QtWidgets/QApplication>
#include <QDialog>
class Dialog : public QDialog {
public:
Dialog(QWidget* parent = nullptr, Qt::WindowFlags flags = 0) :
QDialog(parent, flags) {
setWindowTitle("Example");
setSizeGripEnabled(true);
}
};
int main(int argc, char* argv[])
{
QApplication a(argc, argv);
Dialog dlg(nullptr, Qt::FramelessWindowHint); // frameless
return dlg.exec();
}
Result
As all the options are working straightforwardly, I'd suggest you to carefully review your code/UI design for things like setting a maximum/minimum size (if both are the same, the grip will still be available but won't change the size at all).

setMainQmlFile`, rootObject and showExpanded are not members of QQmlApplicationEngine

I've written this piece of code following some guys tutorial but I can't get it to run. The error says:
setMainQmlFile`, rootObject and showExpanded are not members of
QQmlApplicationEngine
What it's supposed to do is get a signal from QML and print out a message (in console). Basically I'm trying to integrate C++ and QML.
EDIT
I've tried to replace some of the functions with some others that seemed appropriate (at least to me). I've also tried to find what to include so that these functions would work but with no luck.
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include "qtquickglobal.h"
#include <QQmlContext>
#include "myclass.h"
#include <QtCore>
#include <QtDebug>
#include <QQuickWindow>
int main(int argc, char *argv[]){
//Q_OBJECT;
QGuiApplication app(argc, argv);
QQmlApplicationEngine viewer;
viewer.load(QUrl(QStringLiteral("Qt/Versuch2/main.qml")));
myclass data;
viewer.rootContext() ->setContextProperty("myclassData", &data);
viewer.setMainQmlFile(QStringLiteral("qml/Versuch2/main.qml"));
QObject *viewerobject = viewer.rootObject();
QObject::connect(viewerobject, SIGNAL(qmlSignal(QString)), &data, SLOT(cppSlot(QString)));
viewer.showExpanded();
return app.exec();
}
void myclass::cppSlot(QString msg) {
qDebug() <<QString ("Called the cpp slot with message: %1").arg(msg);
}
Thank You.
I don't know where did you find you tutorial but, regarding Qt documentation, there is no such methods as setMainQmlFile nor showExpanded for QQmlApplicationEngine.
For setMainQmlFile(...), try to use instead setSource(...).
For showExpanded(), it's a QWidget function, and QQmlApplicationEngine do not inherit QWidget.
Regarding rootObject(), it might be a typo, you can use rootObjects() which return a QList<QObject*>.
Edit: Looks like you'll have to use the Qt Quick 2 Application wizard of Qt Creator in order to re-create that QtQuick2ApplicationViewer class used in the tutorial you found.
Using Qt 5.4.0 and Qt Creator 3.3.0, create New Project:
Click New Project
Qt Quick Application
Click Choose...
Name the project and select where to place it
Click Next
Select Qt Quick 2.4 from the drop-down menu
Click Next
Select desired Kit(s)
Click Next
Click Finish
Now You should see open main.qml file with following code:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
Qt.quit();
}
}
}
Make changes to the file so that it looks like the following:
import QtQuick 2.4
import QtQuick.Window 2.2
Window {
visible: true
//### New Code ###
signal myQmlSignal(string msg)
//################
MainForm {
anchors.fill: parent
mouseArea.onClicked: {
//### New Code ###
//Replace "Qt.quit();" with
console.log("Sending myQmlSignal from QML...");
myQmlSignal("Hello from QML")
//################
}
}
}
Add new class to Your project:
Right Mouse Click project name in Projects viewer
Click Add New...
Select C++ Class if not already selected
Click Choose...
In Class name filed enter "MyCppClass"
Set Base class to QObject
Click Next
Click Finish
Open mycppclass.h file, it should look like the following:
#ifndef MYCPPCLASS_H
#define MYCPPCLASS_H
#include <QObject>
class MyCppClass : public QObject
{
Q_OBJECT
public:
explicit MyCppClass(QObject *parent = 0);
~MyCppClass();
signals:
public slots:
};
#endif // MYCPPCLASS_H
Make changes to mycppclass.h so it looks like this:
#ifndef MYCPPCLASS_H
#define MYCPPCLASS_H
#include <QObject>
//### New Code ###
#include <QDebug>
//################
class MyCppClass : public QObject
{
Q_OBJECT
public:
explicit MyCppClass(QObject *parent = 0);
~MyCppClass();
signals:
public slots:
//### New Code ###
void myCppSlot(const QString &msg);
//################
};
#endif // MYCPPCLASS_H
Open mycppclass.cpp, which should look like this:
#include "mycppclass.h"
MyCppClass::MyCppClass(QObject *parent) : QObject(parent)
{
}
MyCppClass::~MyCppClass()
{
}
Change it to this:
#include "mycppclass.h"
MyCppClass::MyCppClass(QObject *parent) : QObject(parent)
{
}
MyCppClass::~MyCppClass()
{
}
void MyCppClass::myCppSlot(const QString &msg)
{
//### New Code ###
qDebug() << "Signal was received by C++. It contains follwoing message: " << msg;
//################
}
Open main.cpp, which looks like this:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
And make following changes:
#include <QGuiApplication>
#include <QQmlApplicationEngine>
//### New Code ###
#include "mycppclass.h"
//################
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
//### New Code ###
MyCppClass myCppClass;
QObject::connect(engine.rootObjects().takeFirst(), SIGNAL(myQmlSignal(QString)), &myCppClass, SLOT(myCppSlot(QString)));
//################
return app.exec();
}
Click big green triangle to compile and run Your application. Watch Application Output area, click Hello World, You should see following message being printed out:
qml: Sending myQmlSignal from QML...
Signal was received by C++. It contains follwoing message: "Hello from QML"

QObject::connect: No such slot mywindow::changerLargeur(int)

i read other questions about the same issue but wasn't able to solve mine. When i run my code, the program starts, send QObject::connect: No such slot mywindow::changerLargeur(int) and then fails.
thanks you for your help
h file
#ifndef MYWINDOW_H
#define MYWINDOW_H
#include <QWidget>
#include <QSlider>
#include <QLCDNumber>
class mywindow : public QWidget
{
Q_OBJECT
public:
mywindow();
public slots:
void changerlargeur(int largeur);
private:
QSlider *glisseur;
QLCDNumber *afficheur;
};
#endif // MYWINDOW_H
cpp file
#include "mywindow.h"
mywindow::mywindow(): QWidget()
{
setFixedSize(200, 100);
glisseur = new QSlider(Qt::Horizontal,this);
glisseur->setRange(100,900);
glisseur->setGeometry(10, 60, 150, 20);
QObject::connect(glisseur, SIGNAL(valueChanged(int)), this, SLOT(changerLargeur(int)));
QObject::connect(glisseur, SIGNAL(valueChanged(int)), afficheur, SLOT(display(int)));
afficheur = new QLCDNumber(this);
afficheur->setSegmentStyle(QLCDNumber::Flat);
}
void mywindow::changerlargeur(intlargeur)
{
setFixedSize(largeur, 100);
}
main file
#include <QApplication>
#include "mywindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
mywindow fenetrep;
fenetrep.show();
return app.exec();
}
Like most other things in C++, Qt's signals and slots are case sensitive. So this won't work:
void changerlargeur(int largeur);
vs.
SLOT(changerLargeur(int))
You need to decide whether you want the L to be upper or lower case and stick with it.
Another issue is this:
QObject::connect(glisseur, SIGNAL(valueChanged(int)), afficheur, SLOT(display(int)));
afficheur = new QLCDNumber(this);
You can't connect to a slot on an object that doesn't exist yet.

Why does this code create two objects while one is needed?

This is a tutorial code for Qt:
Header file:
#include <QMainWindow>
namespace Ui {
class Notepad;
}
class Notepad : public QMainWindow
{
Q_OBJECT
public:
explicit Notepad(QWidget *parent = 0);
~Notepad();
private:
Ui::Notepad *ui;
};
Source file:
#include "notepad.h"
#include "ui_notepad.h"
Notepad::Notepad(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::Notepad)
{
ui->setupUi(this);
}
Notepad::~Notepad()
{
delete ui;
}
And in main,
#include "notepad.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Notepad w;
w.show();
return a.exec();
}
So when we do Notepad w, an object is already created on the stack, and why does the code still create another object on the heap using new and assign to a member?
The one on the stack is of type Notepad, and it's the application's main window. The dynamic one is of type Ui::Notepad. That's a class automatically generated by Qt's uic tool; it contains the widgets created in UI creator as data members.
In a way, you could say that Notepad is concerned with the logic and uses an instance of Ui::Notepad to provide the GUI for it.