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
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.
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.)
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)
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)
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.