QWidget winId crashing if called from constructor - c++

I'm writing a program, where i callQWidget::winId()in the constructor:
debug_window::debug_window(QWidget *parent) :
QDialog(parent),
ui(new Ui::debug_window),
hk(NULL)
{
this->ui->setupUi(this);
this->hk = new TestClass(this, this->winId())
}
But this will cause my program to crash, even before a window is created. I already figured out that the call of winId causes the crash, probably because at this time there is no window existing. (correct me if I'm wrong).
Sadly, there is no signal "windowCreated()" or something similar. So is there any way to find out that the window was created, or how to in general solve this problem?
Thanks for your help.

Create signal and emit him in the end of constructor.

Related

Qt action won't connect to slot

Writing a school project in c++ and qt. It is supposed to be a block editor (like draw.io). I generate blocks as a buttons and setting them to a grid. Each button is supposed to have own menu to be able to get edited, deleted, etc. (image example:
We are encountering a problem, that our action won't connect to a slot. Function akceAkce is supposed only to print 1 onto output (via qInfo). But when I click on the menu button, it does nothing. Any suggestions appreciated. Thanks!
void BlockItem::createButton() {
this->button = new QPushButton("+");
this->buttonMenu = new QMenu(this->button);
this->connectBlocks = new QAction(tr("Connect"), this->buttonMenu);
connect(this->connectBlocks, &QAction::triggered, this, &BlockItem::akceAkce);
this->buttonMenu->addAction(this->connectBlocks);
this->button->setMenu(this->buttonMenu);
}
void BlockItem::akceAkce() {
qInfo("1");
}
I would suggest a possible explanation: you put the BlockItem instance on the stack, and it's going out of scope somewhere in your code, and destroyed consequently, while the push button, menu and action all survive it, since they're instantiated with new, thus they live on the heap.
Something like this:
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
BlockItem blockitem;
blockitem.createButton();
ui->gridLayout->addWidget(blockitem.getButton());
}
In the sample code above, blockitem goes out of scope at the end of the method, so it is destroyed and the connection loses its receiver side (i.e. breaks).
The same would happen if you instantiate a BlockItem object on the heap, using new, but accidentally delete it somewhere. Again, the signal sender (the QAction object) survives the receiver and the connection is broken.

Compilation issue with qt_screen

I have Qt5.5 Installed on Desktop PC On Ubuntu OS.
While compiling my program i am getting below error -
This is what i got for error
../../work/mainwindow.cpp: In constructor 'MainWindow(QWidget)':
../../work/mainwindow.cpp:63:31:
error: 'qt_screen' was not declared in this scope ui->stackedWidget-
>resize(qt_screen->deviceWidth(),qt_screeb->deviceHeight());
And this is part of my code
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setipUi(this);
setWindowFlags(Qt::CustomizeWindowHint);
ui->stackedWidget->resize(qt_screen->deviceWidth().qt_screen->deviceHeight());
ui->stackedWidget->setCurrentWidget(ui->stackedWidgetPageMain);
initPageMain();
touch=new Touch();
powerButton=new PowerButton();
auxButton=new AuxButton();
usbOtg=new UsbOtg();
battery=new Battery();
panel=new Panel();
lan=new Lan();
hPattern= new HPattern();
lodLog=new LodLog();
record=new Record();
led=new Led();
lightsensor=new LightSensor();
}
Did i miss to include anything?
By the way i'm sure that i had include Qscreen into it.
Is there any possibility that i might set wrong on my code?
QScreen class has changed notably from Qt4 and Qt5, actually so much, that it is considered new in Qt5.
Qt4 QScreen had a static method called QScreen::instance() which returned a QScreen instance pointer. Way back in Qt4, this pointer was taken from a global variable qt_screen, if I remember correctly.
All this has changed, so simply remove all code which access qt_screen and fix it by properly accessing public APIs.

Qt5 Signal and slots does not seem to work

I am trying to change a label's text to a slider's value when the slider moves. My slider is named sld_bet and my label is lbl_bet. sld_bet_changed() is a function that only has a breakpoint in it, and will eventually contain lbl_bet's modifying code.
The breakpoint is never reached, and I do not understand why.
app::app(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
connect(ui.sld_bet, SIGNAL(ui.sld_bet->sliderMoved()),
this, SLOT(sld_bet_changed()));
}
change to
connect(ui.sld_bet, SIGNAL(sliderMoved()), this, SLOT(sld_bet_changed()));
If you are using Qt 5, use the new connect syntax. That way the compiler will throw an error if something is not correct.
connect(ui.sld_bet, &QSlider::sliderMoved, this, &app::sld_bet_changed);

Qt::WA_DeleteOnClose

I am learning Qt and trying some examples in the book "Foundations of Qt Development".
In the book, there is a section teaching Single Document Interface with an example creating a simple app like a notepad.
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
setAttribute(Qt::WA_DeleteOnClose);
setWindowTitle(QString("%1[*] - %2").arg("unnamed").arg("SDI"));
connect(ui->docWidget->document(), SIGNAL(modificationChanged(bool)), this, SLOT(setWindowModified(bool)));
createActions();
createMenu();
createToolbars();
statusBar()->showMessage("Done");
}
The book said that "Setting the windows attribute to Qt::WA_DeleteOnClose so that Qt takes care of deleting the window from memory as soon as it is closed.
How it works?
Because if i use setAttribute(Qt::WA_DeleteOnClose);, when I end the program, there is a Debug Assertion Failed warning:_BLOCK_TYPEIS_VALID(pHead->nBlockUse).
There is no problem if the setAttribute is removed.
Qt takes care of the deletion by itself if you set all the parenting right (if you create a new QObject/QWidget set the parent in the constructor). If the parent will be destructed, then the children will be too. In your main file, you can create the mainwindow on the stack, such that it will be destructed at the end of scope.
To call addToolbar you don't need this->, since it is a method of the class anyway.
The toolbar ptr should be a member to access it easily later on. But initialize it with nullptr (or NULL if you don't have c++11) in the initialization list of the constructor to know whether it is initialized or not.
The addToolBar call should work. A workaround would be to create a QToolBar on your own and add the pointer to the MainWindow using another addToolBar overload.

Fullscreen for QDialog from within MainWindow only working sometimes

(Testing with C++ on Qt 4.8 and Ubuntu 12.10 unity)
I've got a main window which displays a QDialog. When I put the Dialog window full-screen it does not seem to always work even though it seems to be a proper window.
Meaning, the window can appear full-screen, though only sometimes.
Anyone got an idea? I know Qt states it might not work for all X environments, but it can't be that bad, can it?
MainWindow::MainWindow(QWidget *parent) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
QDialog* d = new QDialog();
d->setModal(false);
d->show();
qDebug() << d->isWindow();
// works most of the times, though not always:
// d->showFullScreen();
// sometimes works, sometimes it doesn't:
QTimer::singleShot(2000, d, SLOT(showFullScreen()));
}
DomTomCat here at stackoverflow showed a way to detect Ubuntu and the QDialog problem is related to a bug in Metacity (Ubuntu's default window manager).
Metacity doesn't manage the same way dialogs and main windows and it has to be tricked making it think that a QDialog is a normal window. In order to do so using QDialog class it's window flags have to be changed.
Instead of doing all the steps DomTomCat says, you can detect the session and then just
//example inside the QDialog
this->setWindowFlags(Qt::Window);
this->showFullScreen();
The bug was reported (and ignored) before but as far as I know this is the first simple workaround.
https://bugreports.qt.io/browse/QTBUG-16034
https://git.gnome.org/browse/metacity/tree/src/core/window.c#n6326
Ubuntu can also use compiz. This can be seen at:
grep DefaultProvider-windowmanager /usr/share/gnome-session/sessions/*
Best regards,
Iker De Echaniz.
I came to a method, which works. I don't know why it works compared to just calling showFullScreen(). I guess this is not the perfect and clean solution. This can surely be adapted to other environmental variables and X sessions.
QDialog* d = new QDialog();
d->setModal(false);
d->show();
const QString session = QString(getenv("DESKTOP_SESSION")).toLower();
QByteArray geometry;
if (session == "ubuntu") {
geometry = _d->saveGeometry();
d->setFixedSize(qApp->desktop()->size());
d->setWindowFlags(Qt::FramelessWindowHint);
d->setWindowState( d->windowState() | Qt::WindowFullScreen);
d->show();
d->activateWindow();
} else {
d->showFullScreen();
}
For restoring from the fullscreen state, this has worked
if (session == "ubuntu") {
d->setMaximumSize(QWIDGETSIZE_MAX, QWIDGETSIZE_MAX);
d->setMinimumSize(0,0);
d->restoreGeometry(geometry);
d->setWindowFlags(Qt::Dialog);
d->show();
d->activateWindow();
} else {
d->showNormal();
}