Home > Back-end >  Connect QPushButton in the QDialog in one header file with method in another header file
Connect QPushButton in the QDialog in one header file with method in another header file

Time:12-24

I've got such a project set up in CMakeLists.txt: (It's a window that opens in the maximized size. There is one button in it. When the button will be pressed - a popup window appears)

cmake_minimum_required(VERSION 3.5)

project(ADB VERSION 0.1 LANGUAGES CXX)

set(CMAKE_INCLUDE_CURRENT_DIR ON)

set(CMAKE_AUTOMOC ON)
set(CMAKE_AUTOUIC ON)
set(CMAKE_AUTORCC ON)

set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_STANDARD_REQUIRED ON)

find_package(Qt6 COMPONENTS Quick Widgets REQUIRED)

set(SRC_DIR "${CMAKE_SOURCE_DIR}/src")
set(HEADERS_DIR "${CMAKE_SOURCE_DIR}/headers")

set(GLOB_RECURSE
    "${SRC_DIR}/main.cpp"
    "${HEADERS_DIR}/mainwindow.cpp"
    "${HEADERS_DIR}/mainwindow.hpp"
    "${HEADERS_DIR}/profilecreator.cpp"
    "${HEADERS_DIR}/profilecreator.hpp"
)

include_directories(${SRC_DIR})
include_directories(${HEADERS_DIR})

qt_add_executable(
    appADB
    WIN32
    "${GLOB_RECURSE}"
)

set_target_properties(
    appADB PROPERTIES
    MACOSX_BUNDLE_GUI_IDENTIFIER my.example.com
    MACOSX_BUNDLE_BUNDLE_VERSION ${PROJECT_VERSION}
    MACOSX_BUNDLE_SHORT_VERSION_STRING ${PROJECT_VERSION_MAJOR}.${PROJECT_VERSION_MINOR}
    MACOSX_BUNDLE TRUE
    WIN32_EXECUTABLE TRUE
)

target_link_libraries(
    appADB
    PRIVATE Qt${QT_VERSION_MAJOR}::Widgets
    PRIVATE Qt${QT_VERSION_MAJOR}::Gui
)

install(TARGETS appADB
    BUNDLE DESTINATION .
    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR})

if(QT_VERSION_MAJOR EQUAL 6)
    qt_finalize_executable(ADB)
endif()

I've got MainWindow class, that is simply initiate popup window by pressing QPushButton 'createP':

#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QWidget>
#include <QDialog>

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

private:
    QDialog* popup;

};
#endif  // MAINWINDOW_HPP

in the mainwindow.cpp:

#include "mainwindow.hpp"
#include "profilecreator.hpp"

#include <QVBoxLayout>
#include <QGroupBox>
#include <QPushButton>
#include <QLineEdit>

MainWindow::MainWindow(QWidget* parent) : QWidget(parent)
{
    QPushButton* createP = new QPushButton("Create profile");
    createP->setStyleSheet("background-color: gray;");
    createP->setFixedSize(100, 25);
    createP->setToolTip("Create profile");

    QHBoxLayout* creationControls = new QHBoxLayout;
    controls->addWidget(createP);

    QGroupBox* controlsBox = new QGroupBox;
    controlsBox->setLayout(controls);

    // Add box the main layout
    QVBoxLayout* mainLayout = new QVBoxLayout;
    // add controls
    mainLayout->addWidget(controlsBox);

    setLayout(mainLayout);

    // Customize window
    setWindowTitle(tr("Checkbuttons table"));
    resize(1000, 1000);

    //==============Pop-up section=================

    // Create the popup window
    popup = new ProfileCreator();

    // Set the Qt::Popup window flag
    // NOTE: You can set flags only here, in the mainwindow where you instantiate popup class
    // otherwise: popup don't close correctly
    popup->setWindowFlags(windowFlags() | Qt::Popup);

    // Connect the createP button's clicked signal to the popup window's show slot
    QObject::connect(createP, &QPushButton::clicked, this, [&]() { popup->show(); });
        //<--- everything is good whith connecting 'createP' button and showing popup dialog

    // Connect create button from popup dialog to the addRow() method
    QObject::connect(popup, &ProfileCreator::createProfileClicked, this, [&]() { qDebug() << "you pressed"; });
       //<--- PROBLEM here. No instance of connect method for such actions
       // if I could simply log that I pressed a QDialog's button that would be enough for now
}

MainWindow::~MainWindow()
{
}

So in the ProfileCreator class are inherit QDialog class. In the header file:

#ifndef PROFILECREATOR_HPP
#define PROFILECREATOR_HPP

#include <QDialog>
#include <QPushButton>
#include <QLineEdit>

class ProfileCreator : public QDialog
{
    Q_OBJECT

signals:
    void createProfileClicked();

public:
    ProfileCreator();

    QPushButton* create;
};

#endif  // PROFILECREATOR_HPP

In the implementation file:

#include "profilecreator.hpp"
#include <QVBoxLayout>

ProfileCreator::ProfileCreator()
{
    // Set the size of the popup window
    this->resize(800, 1200);

    create = new QPushButton("Create");

    // Set the size policies of the widgets to Fixed
    create->setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);

    // Create a layout for the widgets
    QVBoxLayout* layout = new QVBoxLayout();

    // Add the widgets to the layout
    layout->addWidget(create);
    layout->addStretch();

    // Set the layout of the popup window
    this->setLayout(layout);

    // Emit signal of pushing the create new profile button when it pressed
    QObject::connect(create, &QPushButton::clicked, this, [&]() { emit createProfileClicked(); });
        //<--- So with previous line I want to send a signal that QDialog's button is clicked.
        //In the MainWindow constructor class I connect to such signal
}

And in main.cpp:

#include "mainwindow.hpp"

#include <QApplication>

int main(int argc, char* argv[])
{
    // Invoke application, just to appear everything else
    QApplication app(argc, argv);

    // Here we keep all widgets
    MainWindow window;

    // Use the following if you want to have the app open as maximized window:
    window.setWindowState(Qt::WindowMaximized);

    // Show window to application
    window.show();

    return app.exec();
}

So what I do and what I expect to get in a few steps:

  1. I create popup window as a ProfileCreator class inherited from QDialog;
  2. In ProfileCreator class I have QPushButton* create;
  3. When I press create in the ProfileCreator object will be emitted createProfileClicked signal.
  4. In the MainWindow class I initialize a pointer to the ProfileCreator object, 'popup'.
  5. Also in the MainWindow class I create a QPushButton* createP.
  6. I connect createP &QPushButton::clicked signal with popup show() method. And popup should show up. <--- No problems until this point.
  7. I also want to connect a QPushButton* create from ProfileCreator to the lambda: &{qDebug() << "you pressed";}. To log a message - for start.

But it seems that I don't know how to do a connection for step 7.

So, can anyone tell me how to connect the button from the popup window in one class with slots in another class? I know that if a popup window will be created in the constructor of MainWindow there wouldn't be a problem connecting. But I want to organize my code and separate MainWindow from ProfileCreator popup window.

CodePudding user response:

First control variable is not defined in your code, you may fix it with :

QHBoxLayout* creationControls = new QHBoxLayout;
creationControls->addWidget(createP);

QGroupBox* controlsBox = new QGroupBox;
controlsBox->setLayout(creationControls);

About the connection issue ("step 7"), popup is of type QDialog * so your custom signal is not available as a QDialog :

#ifndef MAINWINDOW_HPP
#define MAINWINDOW_HPP

#include <QWidget>
#include <QDialog>

#include "profilecreator.hpp"

class MainWindow : public QWidget
{
    Q_OBJECT

public:
    MainWindow(QWidget* parent = nullptr);
    ~MainWindow();

private:
    ProfileCreator* popup; // instead of QDialog *

};
  • Related