1
votes

mainwindow.h:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>

namespace Ui {
class MainWindow;
}

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}

main.cpp

#include <QtGui/QApplication>
#include "mainwindow.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    QObject::connect(pushButton, SIGNAL(clicked()),
            &a, SLOT(quit()));

    return a.exec();
}

All the codes are given above. In a general Qt GUI program, I put a pushButton on the UI Form and tried to use it in main.cpp. But below error was given:

main.cpp:10: Error:'pushButton' was not declared in this scope

Could you please give me a solution? How can I call it in main.cpp? Thanks!

Complement1:

mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);

    QObject::connect(ui->pushButton, SIGNAL(clicked()),
            QCoreApplication::instance(), SLOT(close()));
}

MainWindow::~MainWindow()
{
    delete ui;
}

If I do it this way, then the program can run but cannot close the whole application. I guess that is because the QCoreApplication::instance() returns null due to in the constructor phase the QApplication doesn't exist, right?

Complement2:

mainwindow.cpp

void MainWindow::on_pushButton_clicked()
{
    close();
}

One solution is to add new slot of the pushButton in mainwindow.cpp, like above. But still I hope to know how to do it my way (main part of this post)?

Complement3:

Alberto's code works fine by using QWidget as below way.

ui->setupUi(this);
connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(close()));
1
Why do you need to call it in main.cpp so badly?Ancurio
Then how to do? I need to quit the whole application, but the 'a' points to the whole application is in main.cpp, so I put the code in it.Tom Xue
You can always retrieve a pointer to the current Q(Core)Application by calling the static QCoreApplication::instance() function, from anywhere in your code.Ancurio
Thanks for your answer! Please check my main post above, Complement1 part.Tom Xue
Why do you connect to a "close" SLOT? QCoreApp doesn't have that. What you're looking for is the "quit" SLOT. (ref)Ancurio

1 Answers

1
votes

Your first approach can't work because, as compiler says, you didn't defined a QPushButton in main.cpp scope. So compiler can't find it.

Right approach is your last one. You develop a .ui file in which you add a QPushButton and then in c++ code that handles your .ui file(in your example a QMainWindow subclass) you connect it with a slot. But your connect call is wrong. This is my code:

//widget.h:
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>

namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    ~Widget();
private:
    Ui::Widget *ui;
};

#endif // WIDGET_H

//widget.cpp:
#include "widget.h"
#include "ui_widget.h"

#include <QtGui>

Widget::~Widget()
{
    delete ui;
}

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);
    connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(close()));
}


//widget.ui:
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>Widget</class>
 <widget class="QWidget" name="Widget">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>93</width>
    <height>41</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Widget</string>
  </property>
  <layout class="QVBoxLayout" name="verticalLayout">
   <item>
    <widget class="QPushButton" name="pushButton">
     <property name="text">
      <string>PushButton</string>
     </property>
    </widget>
   </item>
  </layout>
 </widget>
 <layoutdefault spacing="6" margin="11"/>
 <resources/>
 <connections/>
</ui>


//main.cpp:
#include <QtGui/QApplication>
#include "widget.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

with: connect(ui->pushButton,SIGNAL(clicked()),this,SLOT(close())); which we can simplify in this way: connect(1,2,3,4);

when 2 is emitted because user does something on 1, do 4 on 3.

translated: when user click on pushButton(defined into ui file), do close on this(QMainWindow subclass). And if you take a look at your main.cpp code, MainWindow is the main widget you show to the user. So you're closing the whole app.