i just started learning Qt few days ago, and i have a problem that i can't solve.
First there is the files :
main.cpp
#include <QApplication>
#include "test.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
test w;
w.show();
return a.exec();
}
test.h
#ifndef TEST_H
#define TEST_H
#include <QWidget>
#include <QTabWidget>
#include <QTextEdit>
#include <QPushButton>
class test : public QWidget
{
Q_OBJECT
public:
test();
~test();
private slots:
void addT();
private :
QTabWidget *tab;
QPushButton *b,*c;
};
#endif // TEST_H
and test.cpp
#include "test.h"
test::test()
{
QTabWidget *tab = new QTabWidget(this);
QPushButton *b = new QPushButton("Add",this);
tab->addTab(b,"test");
QObject::connect(b,SIGNAL(clicked()),this,SLOT(addT()));
}
test::~test()
{
}
void test::addT()
{
QPushButton *c= new QPushButton("Add",this);
tab->addTab(c,"test");
}
the program starts normally but when i push the button to add a new Tab it crashes
Please Help me!
In your constructor you are not assigning to the QTabWidget and QPushButton instanced declared in your header, but are creating two new instances (with the same name) that will be gone at the end of the scope. The tab instance is still a nullptr and when trying to derefence it in addT, your program will crash. You need to assign to the variables declared in test.h like this:
test::test() : tab(new QTabWidget(this), b(new QPushButton("Add", this) {
...
}
Related
I'm trying to add an objects (that inherits from QWidget) as a child to another QWidget as shown below, it works perfectly with another normal QWidget instance but not with my custom class, any idea why ?
fenetre.h
#ifndef FENETRE_H
#define FENETRE_H
#include <QWidget>
#include <QMouseEvent>
class Fenetre : public QWidget
{
Q_OBJECT
public:
Fenetre();
};
#endif // FENETRE_H
fenetre.cpp
#include "fenetre.h"
Fenetre::Fenetre() : QWidget()
{
}
main.cpp
#include <iostream>
#include <QApplication>
#include <QWidget>
#include "fenetre.h"
int main(int argc, char *argv[])
{
QApplication app(argc,argv);
QWidget window;
window.setFixedSize(800,600);
//This appears
QWidget rec1;
rec1.setParent(&window);
rec1.setFixedSize(100,100);
rec1.move(400,200);
rec1.setStyleSheet("background-color: red");
//This one not
Fenetre rec2;
rec2.setParent(&window);
rec2.setFixedSize(100,100);
rec2.move(200,200);
rec2.setStyleSheet("background-color: green");
window.show();
return app.exec();
}
PS: I did research on the platform, but the majority of the answers speak of the use of a layout. Thank you !
you miss the parent:
//header .h
class Fenetre : public QWidget
{
Q_OBJECT
public:
Fenetre(QWidget *parent = 0);
};
//source .cpp
Fenetre::Fenetre(QWidget *parent) : QWidget(parent)
{
}
I would like to make some modifications of the main window from another file.
I created another ui file Form1Window (which open when a button is cliked in the MainWindow).
I want to call from the class Form1Window a function named test() of the MainWindow class
I succeed in calling function test() but I can't execute the whole content of the function (I can display a message but can't execute the part where I want to clear an edittext)
MainWindow.h
#include "form1window.h"
public slots:
void nettoyer();
private slots:
void openFrom1();
private:
Ui::MainWindow *ui;
From1Window *uiFrom1;
};
MainWindow.cpp
void MainWindow::openFrom1()
{
uiFrom1 = new From1Window(this);
uiFrom1->show();
}
void MainWindow::nettoyer(){
QMessageBox msgBox;
msgBox.setText("test");
msgBox.setIcon(QMessageBox::Information);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.exec();
ui->auteur->clear();
//THIS LINE HAS NO EFFECT WHEN CALLED FROM THE OTHER CLASS
}
form1window.cpp
#include "mainwindow.h"
#include "ui_form1window.h"
void From1Window::on_supprimer_clicked()
{
MainWindow *a=new MainWindow ();
a->test();
close();
}
I've read about the role of the pointer of MainWindow class (C++ /Qt Proper way to access ui from another class in qt //Edited) and I've also tried connect()
Thank for your help
//THIS LINE HAS NO EFFECT WHEN CALLED FROM THE OTHER CLASS
this->ui->auteur->clear();
The line will never executed unless you dismiss QMessageBox. This is because you triggered QMessageBox with exec() function. This function has its own event queue and does not return until finishes. You may set QMessageBox as modal and display it with show() method. In that case QMessageBox will not block execution of the the flow.
This problem can also happen with QDialog(s) if you display them with exec().
I provide you a simple two window signal/slot example:
main.cpp
#include "mainwindow.h"
#include "form.h"
#include <QApplication>
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
Form f;
f.show();
return a.exec();
}
form.h
#ifndef FORM_H
#define FORM_H
#include <QWidget>
#include <QPushButton>
class Form : public QWidget
{
Q_OBJECT
public:
explicit Form(QWidget *parent = 0);
~Form();
private:
QPushButton *pb;
};
#endif // FORM_H
form.cpp
#include "form.h"
#include "mainwindow.h"
#include <QDebug>
Form::Form(QWidget *parent) : QWidget(parent)
{
MainWindow *mw = new MainWindow();
pb = new QPushButton("clickME", this);
QObject::connect(pb, SIGNAL(clicked()), mw, SLOT(test()));
mw->show();
}
Form::~Form()
{
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QLabel>
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0);
~MainWindow();
public slots:
void test();
private:
QLabel *l;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
{
l = new QLabel("test", this);
}
MainWindow::~MainWindow()
{
}
void MainWindow::test() {
qDebug() << "test called!" << endl;
l->setText("text changed");
}
This works for me.
output
I have a problem with my Qt code. I wanted to write an program which are taking a coordinates of point and then that point is drawing in point with that coordinates. My program doesn't have any errors or warnings when i built it but it's crashing at start(MainWindow doesn't show). This is my code:
main.cpp
#include < QApplication >
#include "mainwindow.h"
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow win;
win.show();
return app.exec();
}
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QWidget>
#include <QAction>
#include <QToolBar>
#include <QTextCodec>
#include <QObject>
#include <QDialog>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
#include "addpoint.h"
class MainWindow: public QMainWindow
{
Q_OBJECT
private:
QToolBar *AddToolbar;
QAction *AddPointAction;
AddPoint *AddPointDialog;
QLineEdit *x;
public:
MainWindow();
void createToolbar();
void createActionAdd();
signals:
public slots:
void PointClicked();
void DialogAccepted();
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow()
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createActionAdd();
createToolbar();
connect(AddPointAction, SIGNAL(triggered(bool)), this, SLOT(PointClicked()));
connect(AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
setMinimumSize(480, 320);
}
/**/
void MainWindow::createToolbar()
{
AddToolbar = new QToolBar;
AddToolbar->addAction(AddPointAction);
addToolBar(AddToolbar);
}
/**/
void MainWindow::createActionAdd()
{
AddPointAction = new QAction("Add Road", this);
x = new QLineEdit(this);
x->setFixedSize(100, 30);
x->move(100, 100);
}
/**/
void MainWindow::PointClicked()
{
AddPointDialog = new AddPoint(this);
AddPointDialog->setModal(true);
AddPointDialog->exec();
}
/**/
void MainWindow::DialogAccepted()
{
x->setText("abc");
}
addpoint.h
#ifndef ADDPOINT_H
#define ADDPOINT_H
#include <QWidget>
#include <QTextCodec>
#include <QDialog>
#include <QObject>
#include <QLabel>
#include <QLineEdit>
#include <QPushButton>
#include <QString>
class AddPoint : public QDialog
{
Q_OBJECT
private:
QLabel *XpointL;
QLineEdit *XPoint;
QPushButton *OKButton;
public:
AddPoint(QWidget *parent);
void createButton();
signals:
public slots:
};
#endif // ADDPOINT_H
addpoint.cpp
#include "addpoint.h"
AddPoint::AddPoint(QWidget *parent) :QDialog(parent)
{
QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF-8"));
createButton();
connect(OKButton, SIGNAL(clicked(bool)), this, SLOT(accept()));
setMinimumSize(320, 240);
}
/**/
void AddPoint::createButton()
{
XpointL = new QLabel("Point X:", this);
XpointL->setFixedSize(100, 30);
XpointL->move(10, 10);
XPoint = new QLineEdit(this);
XPoint->setFixedSize(180, 30);
XPoint->move(120, 10);
OKButton = new QPushButton("OK", this);
OKButton->setFixedSize(100, 30);
OKButton->move(200, 150);
}
After running the program i see in aplication output lap:
"The program has unexpectedly finished."
"C:\QT\build-xxx-Desktop_Qt_5_4_2_MSVC2013_64bit-Debug\debug\xx.exe crashed"
I note that i made some experiments with this code and i saw that i have problem with signal accpeted() at mainwindow.cpp. I don't know what can i do with this problem. I hope you will help me.
AddPointDialog is uninitialized pointer, it does not yet point to valid AddPoint in MainWindow's constructor. You cannot call connect on that. Its value will change later, when you do AddPointDialog = new AddPoint(this); and only then will you be able to call connect.
Simply, you should move your connect call to void MainWindow::PointClicked() after you've initialized your pointer. I'd also make AddPointDialog local to that function and store it on the stack (you don't use it anywhere else and you're leaking memory).
The code would be:
void MainWindow::PointClicked()
{
AddPoint AddPointDialog(this);
AddPointDialog.setModal(true);
connect(&AddPointDialog, SIGNAL(accepted()), this, SLOT(DialogAccepted()));
AddPointDialog.exec();
}
Before taking up the main subject, please mind that i`m a beginner of Qt.
I made a AddIm.cpp, and I want to set an image on QLabel in MainWindow.
here is my source in AddIm.cpp
void AddIm::on_pushButton_clicked()
{
MainWindow mainwindow;
mainwindow.setImage();
}
and here is MainWindow.cpp
void MainWindow::setImage()
{
QPixmap pix("./test.jpg");
ui->label->setPixmap(pix);
}
and MainWindow.h
class MainWindow : public QMainWindow
{
public:
void setImage();
~ some source ~
private:
Ui::MainWindow *ui;
};
it doesn't work at all. so I added a button in MainWindow for testing.
and when it clicked, setImage works. but when I execute setImage in AddIm.
it doesn't work. please let me know why
Your problem has nothing to do with your knowledge with Qt but rather your knowledge of c++.
In AddIm::on_pushButton_clicked(), you create a new MainWindow object on the stack, create the image, and then exit the function.
When a function exits, all local stack objects are destroyed. This means that your image is indeed being loaded but the window is being destroyed before you get a chance to see it. Even if it survived to live longer than the function allowed, you never show the window so it remains hidden.
UPDATE:
Change AddIm.cpp to be the following:
void AddIm::on_pushButton_clicked()
{
MainWindow *mainwindow = new MainWindow;
mainwindow->setAttribute(Qt::WA_DeleteOnClose, true);
mainwindow->setImage();
mainwindow->show();
}
Compare this with with your code to see where you might have gone wrong. I tried as much as possible to code it just like you did. I hardly use the designer, i like to code everything. It works as expected.
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QWidget>
#include <QLabel>
#include <QPixmap>
class MainWindow : public QWidget {
Q_OBJECT
public:
void setImage();
private:
QLabel *label;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
void MainWindow::setImage() {
QPixmap pix(":/test.jpg");
label = new QLabel;
label->setPixmap(pix);
label->show();
}
addim.h
#ifndef ADDIM_H
#define ADDIM_H
#include <QMainWindow>
#include <QPushButton>
#include <QHBoxLayout>
#include "mainwindow.h"
class AddIm : public QMainWindow {
Q_OBJECT
public:
AddIm(QWidget *parent = 0);
~AddIm();
private slots:
void on_pushButton_clicked();
private:
QPushButton *button;
};
#endif // ADDIM_H
addim.cpp
#include "addim.h"
AddIm::AddIm(QWidget *parent) : QMainWindow(parent) {
button = new QPushButton("Show Image");
setCentralWidget(button);
connect(button, SIGNAL(clicked()), this, SLOT(on_pushButton_clicked()));
}
void AddIm::on_pushButton_clicked() {
MainWindow mainwindow;
mainwindow.setImage();
}
AddIm::~AddIm() {
}
main.cpp
#include "addim.h"
#include <QApplication>
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
AddIm window;
window.show();
return a.exec();
}
You did not shown the window.
First, you have to create a C++ Class not a single .cpp file. Then add a pointer to the window in your AddIm.h file:
private:
MainWindow* mainwindow;
Then in your AddIm.cpp file:
mainwindow = new MainWindow(this);
mainwindow->setAttribute(Qt::WA_DeleteOnClose, true); // prevent memory leak when closing window
mainwindow->setImage();
mainwindow->show();
And remember to include MainWIndow in AddIm.h
#include "mainwindow.h"
I have this two class in c++
GUI.cpp
#include "AL_GUI.h"
#include <QtGui/QApplication>
#include "mainwindow.h"
GUI::GUI() {
}
void GUI::startGUI(){
int c=1;
char *array[10];
char** v = &array[0];
QApplication qa(c,v);
w.show();
qa.exec();
}
void GUI::notifyAlert(){
}
GUI::~GUI() {
// TODO Auto-generated destructor stub
}
GUI.h
#include <QtGui/QApplication>
#include "mainwindow.h"
#include "mainwindow.h"
#ifndef GUI_H_
#define GUI_H_
class GUI {
public:
GUI();
virtual ~GUI();
void startGUI();
void notifyAlert();
private:
MainWindow w;
};
#endif
But when i run this program i have the error:
QWidget: Must construct a QApplication before a QPaintDevice
How can I declare MainWindow w in gui.h in such a way that I don't receive this error
You can't (well, you can, but you shouldn't). The MainWindon declaration is right where it should be. The problem is that you attempt to create a GUI object before you create the QApplication.
Why not create the QApplication where you create the GUI object, just before it?
I would have made w a pointer used a forward declaration for MainWindow and removed all the includes (including the 2 includes for mainwindow.h) from GUI.h. Then like the answer from Sebastian says construct the QApplication first.
AL_GUI.h
#ifndef GUI_H_
#define GUI_H_
class MainWindow;
class GUI {
public:
GUI();
virtual ~GUI();
void startGUI();
void notifyAlert();
private:
MainWindow* w;
};
gui.cpp
#include "AL_GUI.h"
#include <QtGui/QApplication>
#include "mainwindow.h"
GUI::GUI() : w(NULL)
{
}
void GUI::startGUI(){
int c=1;
char *array[10];
char** v = &array[0];
QApplication qa(c,v);
w = new MainWindow;
w->show();
qa.exec();
}
void GUI::notifyAlert(){
}
GUI::~GUI() {
delete w;
}