QPushButton在单击时未执行连接功能

时间:2020-03-11 23:56:27

标签: c++ qt

我有一个叫UserInterface的课。在此类中,有不同的功能。 build_start_screen()为初始开始屏幕添加所有小部件(标签,按钮等)。 build_option_a_screen()从开始屏幕中删除所有内容,并在用户单击选项A的按钮时添加屏幕所需的所有小部件,依此类推。为了这个问题,班级被剥夺了。

现在,我在build_start_screen()中声明了一个按钮,并将其连接到简单的MessageBox.exec(),因此单击时应弹出该按钮。 但是,单击按钮后什么也没发生。

我在做什么错?与函数完成后变量的生存期有关吗?

#include <QApplication>
#include <QPushButton>
#include <QAbstractButton>
#include <QLabel>
#include <QFont>
#include <QVBoxLayout>
#include <QMessageBox>

//Class handling all the UI in this Application
class UserInterface {
    public:
        //Build the initial UI the user sees
        void build_start_screen(QWidget& window) {
            //Make new QVBoxLayout for this startscreen UI
            this->layout = new QVBoxLayout(&window);

            //Test messagebox
            QMessageBox msgBox;
            msgBox.setText("Button test.");

            //Button to go to Option A-screen
            QPushButton* showMsgBox = new QPushButton("Show pop-up");
            QAbstractButton::connect(showMsgBox, SIGNAL (clicked()), &window, SLOT (msgBox.exec()));

            //Add labels and button to QVBoxLayout
            layout->addWidget(showMsgBox);
        }

    private:
        //Properties
        QVBoxLayout* layout;
};

int main(int argc, char **argv) {
    QApplication app (argc, argv);

    //Initialize Window
    QWidget Window;
    Window.resize(400, 250);     

    //Create new UserInterface object
    //This will allow us to create different user-interfaces
    //depending on the function we call
    UserInterface* ui = new UserInterface();
    ui->build_start_screen(Window);
    Window.show();

    return app.exec();
}

如果我想做同样的事情,但是我不想调用messageBox而是调用另一个函数怎么办?

#include <QApplication>
#include <QPushButton>
#include <QAbstractButton>
#include <QLabel>
#include <QFont>
#include <QVBoxLayout>
#include <QMessageBox>

//Class handling all the UI in this Application
class UserInterface {
    public:
        //Build the initial UI the user sees
        void build_start_screen(QWidget& window) {
            //Make new QVBoxLayout for this startscreen UI
            this->layout = new QVBoxLayout(&window);

            //Test messagebox
            QMessageBox msgBox;
            msgBox.setText("Button test.");

            //Button to go to Option A-screen
            QPushButton* showMsgBox = new QPushButton("Show pop-up");
            QAbstractButton::connect(showMsgBox, SIGNAL (clicked()), &window, SLOT (build_option_a_screen()));

            //Add labels and button to QVBoxLayout
            layout->addWidget(showMsgBox);
        }

        void build_option_a_screen(QWidget& window) {
            //Do stuff here with window
            //e.g
            window.resize(500, 500);
        }

    private:
        //Properties
        QVBoxLayout* layout;
};

int main(int argc, char **argv) {
    QApplication app (argc, argv);

    //Initialize Window
    QWidget Window;
    Window.resize(400, 250);     

    //Create new UserInterface object
    //This will allow us to create different user-interfaces
    //depending on the function we call
    UserInterface* ui = new UserInterface();
    ui->build_start_screen(Window);
    Window.show();

    return app.exec();
}

1 个答案:

答案 0 :(得分:2)

您的代码有2个问题:

  • 窗口“对象”没有错误所指出的插槽“ msgBox.exec()”:

    import requests
    from bs4 import BeautifulSoup
    
    r = requests.get(
        "https://www.bookdepository.com/category/2/Art-Photography/browse/viewmode/all")
    soup = BeautifulSoup(r.text, 'html.parser')
    
    for item in soup.findAll("img", class_="lazy"):
        print(item.get("data-lazy"))
    
  • 更正上面的问题,解决方法是:

    QObject::connect: No such slot QWidget::msgBox.exec() in ../main.cpp:23
    

    但是现在的问题是“ msgBox”是一个本地变量,将被破坏并且无法显示。

所以解决方案是使msgBox成为类的成员或指针(对于指针,必须管理动态内存以避免内存泄漏):

QObject::connect(showMsgBox, &QPushButton::clicked, &msgBox, &QMessageBox::exec);

加号:

建议不要使用旧的连接语法,因为它有局限性并隐藏了问题。

建议不要使用旧的连接语法,因为它有局限性并隐藏了问题。

如果要连接到不是QObject的某种方法(例如,要使用OP的X),则解决方案是使用lambda方法:

//Class handling all the UI in this Application
class UserInterface {
    public:
        //Build the initial UI the user sees
        void build_start_screen(QWidget& window) {
            //Make new QVBoxLayout for this startscreen UI
            this->layout = new QVBoxLayout(&window);
            msgBox.setText("Button test.");
            //Button to go to Option A-screen
            QPushButton* showMsgBox = new QPushButton("Show pop-up");
            QObject::connect(showMsgBox, &QPushButton::clicked, &msgBox, &QMessageBox::exec);

            //Add labels and button to QVBoxLayout
            layout->addWidget(showMsgBox);
        }

    private:
        //Properties
        QVBoxLayout* layout;
        QMessageBox msgBox;
};