Qt - confused on QDialog choice on main - c++

I have the following Qt code:
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
ChoosingDialog cdlg;
if(!startWin.exec())
{
// nothing chosen
return 0;
}
if(cdlg.firstWindowSelected)
{
CFirstWindow win;
win.show();
return app.exec();
}
else
{
CSecondWindow win;
win.show();
return app.exec();
}
}
this seems to work but it's giving me an error on "event dispatcher cleanup" in some asm line. I tried to trick a bit and I saw that the problem is related to the app.exec() calling.
Update:
if I add these lines to the ChoosingDialog (this is a simple blank class auto-generated by Qt Creator)
void ChoosingDialog ::closeEvent(QCloseEvent *)
{
exit(1);
}
I receive no errors

Turns out I was using the "singleapplication" class before the QApplication.. and something went wrong on the shared memory lock.
As soon as I restarted my system the exception disappeared... bof.. do you believe in magic?

Related

How to create QT Login Page bedore Mainwindow?

My Qt windows application is ready, but when the application opens, I want the login dialog to be opened, how can I do this? I'm new to Qt and C++. It would be great if it was descriptive.
You have many ways to achieve that... QDialog is a nice way. Here is a short sample using QInputDialog.
One solution could be to add this code in your main.cpp file, and to load the mainwindow only if the credentials are ok.
#include "gmainwindow.h"
#include <QApplication>
#include <QInputDialog>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
GMainWindow w;
QString login = QInputDialog::getText(NULL, "Login","Name ?",QLineEdit::Normal);
if (login == "USER")
{
w.show();
}
else
{
//display an error message
return a.quit();
}
return a.exec();
}
Of course you may want to put an encrypted password and other things, but the idea will be more or less the same.

Check that the app runs for the first time

I'm new to qt mobile development and I have a rather dumb question.
How would I check whether a user runs the app for the first time (both Android and iOS)?
EDIT:
The reason I need this check is that I have an intro SwipeView for the first-timers and after it's read once it should always open the main app screen.
I've tried the way #TrebledJ suggested and it seems to work alright, Or is this stupid to do that in main.cpp?
#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QSettings>
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
QGuiApplication app(argc, argv);
QSettings settings;
QVariant firstRun = settings.value("first-run");
QQmlApplicationEngine engine;
QUrl startingScreen(QStringLiteral("qrc:/main.qml"));
if(!firstRun.isValid())
settings.setValue("first-run", true);
else
startingScreen.setUrl(QStringLiteral("qrc:/start.qml"));
engine.load(startingScreen);
if (engine.rootObjects().isEmpty())
return -1;
return app.exec();
}
Use QSettings to check for a set value.
QSettings settings;
QVariant val = settings.value("first-time");
if (!val.isValid()) {
// ... first run
settings.setValue("first-time", false); // set a value so that the value is valid on the next run
} else {
// ... not first run
}
In QML, there is the Settings QML Type.
import Qt.labs.settings 1.0
Settings {
id: settings
property bool isFirstTime: true
}
Component.onCompleted: {
if (settings.isFirstTime) {
// ... first run
settings.isFirstTime = false;
} else {
// ... not first run
}
}
However, according to documentation:
Note: This type is made available by importing the Qt.labs.settings module. Types in the Qt.labs module are not guaranteed to remain compatible in future versions.
In consideration of the non-guarantee, Felgo/V-Play's API has a Storage QML Type which can also perform the check in QML. (The first example in their documentation implements this.)

how to take a screenshot Within a QT QTest setting

I'm trying to take a screen shot during some tests where the application is being ran on an iOS simulator.
The app looks something like this:
main.cpp
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
QQmlApplicationEngine engine;
#ifdef TEST
thingTests = new ThingTests(&engine);
tabletTests->startTestSuite(argv[1]);
#endif
...
engine.load(QUrl(QStringLiteral("qrc:/main.qml")));
return app.exec();
}
ThingTests.cpp
TabletTests::TabletTests(QQmlApplicationEngine *engine) : QObject(nullptr), m_testSuiteName(NULL)
{
m_engine = engine;
}
void TabletTests::startTestSuite(char *testSuiteName)
{
m_testSuiteName = testSuiteName;
connect(m_engine, SIGNAL(objectCreated(QObject*,QUrl)), this, SLOT(onObjectCreated(QObject*,QUrl)));
}
void TabletTests::onObjectCreated(QObject *, const QUrl &) {
// run settings test for now, later on control with command line arguments
SettingsTest *settingsTest = new SettingsTest(m_engine);
QTest::qExec(settingsTest);
}
SettingsTest.cpp
void SettingsTest::openWarningModeSelectionTest()
{
m_settingsTester->performTestOperation(SettingsTester::SettingsTestOperation::WarningModeSelection);
QTest::qWait(1000);
bool optionSelectorDisplayed = DialogController::getInstance()->optionSelectorShown();
// This clip came from here: https://stackoverflow.com/questions/21697185/how-to-take-screenshot-of-qml-application-without-qquickview
foreach(QObject* obj, this->m_engine->rootObjects()) {
QQuickWindow* window = qobject_cast<QQuickWindow*>(obj);
if (window) {
QImage image = window->grabWindow(); //<-- This line throws the assertion error
}
}
QVERIFY(optionSelectorDisplayed);
}
I've inherited this codebase and I'm not very familiar with QT, but I tried to only include relevant things in the above snippets.
What I want to be able to do is take some screenshots on what a page looks like at certain times in the tests.
When I have TEST defined, my tests for the app go and do their thing, but they blowup when the window->grabWindow() line is hit with an ASSERT error in assert w in scenegraph/qsgthreadedrenderloop.cpp in the qt libraries. This is the assert that is failing (https://code.woboq.org/qt5/qtdeclarative/src/quick/scenegraph/qsgthreadedrenderloop.cpp.html#1281)

Qt - Dialog in a DLL

In my company, we are developing with Embarcadero-C++-IDE (which is very uncomfortable). To start moving away, we port individual dialogs in a dll to Qt. My qt-dll-code Looks like this for example
extern "C" ROBOTECHPOLYLINEDIALOGSHARED_EXPORT void popupRoboTechDialog()
{
if( ! QApplication::instance() )
{
int argc = 1;
char *argv[] = {"Design polyline"};
QApplication app(argc, argv);
RoboTechPolyline dialog;
dialog.show();
app.exec();
}
else
{
RoboTechPolyline Dialog;
Dialog.exec();
}
}
Trying to start the Dialog from another thread like here Starting Qt GUI from dll (in DLLStart function) did make my Dialog unresponsive, but I don't think the question and mine relate too much.
I'm loading this Dll dynamically from the main-application and it works fine. However, when I make the Dialog Pop up a second time I get an "Access Violation at address .. in module MSVCR110D.dll" and on the third time, I get "ASSERT failure in QCoreApplication , there should be only one application object". So I always Need to Close the whole application in order to make the Dialog appear a second time, which greaty slows down work.
If I add at the bottom the line
QApplication::quit()
the Dialog appears a second time, but the Programm crashes on closing this second Dialog.
The code to load the dll is as follows
HINSTANCE lib = ::LoadLibrary(L"RoboTechPolylineDialog.dll");
if(!lib)
{
ShowMessage("Unable to load RoboTechPolylineDialog.dll");
return;
}
typedef void ( *POPUP_ROBO_TECH_DIALOG )();
POPUP_ROBO_TECH_DIALOG fp = (POPUP_ROBO_TECH_DIALOG) ::GetProcAddress(lib, "popupRoboTechDialog");
if(!fp)
{
ShowMessage("Unable to load function popupRoboTechDialog from RoboTechPolylineDialog.dll");
::FreeLibrary(lib);
return;
}
(*fp)( );
FreeLibrary(lib);
So why am I constructing more than one QApplication at a time? I can in above code replace the line
(*fp)();
with
(*fp)();
(*fp)();
and the Dialog appears twice and everything works greatly. But how can the call to ::FreeLibrary(lib) make things fail.
Can anyone help me? Any help, Workarounds, etc.. is appreciated.
This should work:
#include <QApplication>
#include <QString>
#include <QDialog>
class App {
QApplication *_app;
public:
App(int argc = 0, char** argv = NULL)
: _app(new QApplication(argc, argv))
{
}
~App() {
delete _app;
}
};
void dialog()
{
static int argc = 1;
static char *argv[] = {"Design polyline"};
static App(argc, argv);
QDialog dlg;
dlg.exec();
}
void main()
{
dialog();
dialog();
dialog();
}
Another advice: load Qt libs from as subpath since you could find dll conflict with other apps using it on the same folder (personal experience)

'search' was not declared in this scope

I am trying to learn C++, and I am using the Qt Framework. What I am currently trying to accomplish, is loading a custom font from the resource file. When I run this, File Found is output to the console window. When I uncomment the commented out line I get an error 'search' was not declared in this scope. In the Qt Creator I have objectName set to search. I assumed that I could then access it like how I wrote the commented out line, but I guess I can't. What am I doing wrong?
int main(int argc, char *argv[]){
QApplication a(argc, argv);
Apollo w;
w.show();
int fontID(-1);
QFile res(":/lib/fonts/SourceCodePro-ExtraLight.ttf");
if(res.open(QIODevice::ReadOnly) == true){
fontID = QFontDatabase::addApplicationFontFromData(res.readAll());
if(fontID == -1){
qDebug() << "File Not Found";
}else{
qDebug() << "File Found";
}
}
//search.setFont(QFont("Source Code Pro ExtraLight", 26));
return a.exec();
}
Your object names is "search".
The object is a part of the GUI I guess, so if you want to have acces to it you should do something like that:
ui->search->setFont(...);
Qt creator is quite smart and offer you a kind of auto complement. If it doesn't offer you a proposition for a object of the GUI most of the time that mean you do it wrong.