首页 > 解决方案 > 如何从另一个类编辑 QMainWindow UI 小部件?

问题描述

我需要在另一个源文件中编辑 MainWindow 的 UI 中的 QLabel。我试过搞乱信号和插槽,但老实说,我完全迷路了,Qt 文档在这种情况下对我没有帮助。我知道过去有人问过这个问题,但我还没有找到适合我的解决方案。我是 Qt 和 C++ 的新手。

我有以下代码(大大简化):

“主窗口.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();
    void setFoo(char* text);

private:
    Ui::MainWindow *ui;
};

#endif // MAINWINDOW_H

“主窗口.cpp”

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

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

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

void MainWindow::setFoo(char* text) {
    ui->fooLabel->setText(text);
}

“第二个窗口.h”

#ifndef SECONDWINDOW_H
#define SECONDWINDOW_H

#include <QWidget>

namespace Ui {
class SecondWindow;
}

class SecondWindow: public QWidget {
    Q_OBJECT

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

private:
    Ui::SecondWindow*ui;
}

#endif // SecondWindow_H

“第二个窗口.cpp”

#include "secondwinodw.h"
#include "ui_secondwinodw.h"
#include "mainwindow.h"

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

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

void SecondWindow::on_fooButton_clicked() {
    MainWindow::setFoo("example");//The method is private so this is not possible, but this is my goal
}

当用户单击 fooButton 时,我需要访问和编辑 MainWindow 的 UI QLabel(或执行此操作的公共方法)。没有在 main() 函数中创建第二个窗口

void MainWindow::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_A:
        if (event->modifiers()==Qt::ShiftModifier) {
            SecondWindow*secwind= new SecondWindow();
            secwind->show();
        }
        break;
    }
}

标签: c++qtqt5qt-signalsqtwidgets

解决方案


在 OOP 中,交互的是对象,而不是类或文件,即以下表达式:我需要在另一个源文件中从 MainWindow 的 UI 编辑 QLabel这没有意义,你应该说的是一个对象MainWindow 类的对象被 SecondWindow 类的另一个对象修改。文件不做程序,对象之间的交互做。

我假设这两个对象都是在 main.cpp 中创建的:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w1;
    SecondWindow w2;

    w1.show();
    w2.show();

    return a.exec();
}

现在,如果我要解决主要问题,Qt 处理信号和槽的概念,所以我们将使用它,因为对SecondWindow对象的操作将导致信息被发送,我将创建一个携带该信息的信号:

第二个窗口.h

#ifndef SECONDWINDOW_H
#define SECONDWINDOW_H

#include <QWidget>

namespace Ui {
class SecondWindow;
}

class SecondWindow: public QWidget {
    Q_OBJECT

public:
    explicit SecondWindow(QWidget *parent = 0);
    ~SecondWindow();
signals:
    void messageChanged(const QString & message); // <---
private slots:
    void void SecondWindow::on_fooButton_clicked();
private:
    Ui::SecondWindow*ui;
}

#endif // SecondWindow_H

按下按钮时,必须发出带有信息的信号

第二个窗口.cpp

...
void SecondWindow::on_fooButton_clicked() {
    emit messageChanged("example");//The method is private so this is not possible, but this is my goal
}

现在我们到接收方,我们将如何获得一个插槽,你已经完成但不要使用char *,那是 C,我们使用 C++,更好的是我们使用 Qt,最好使用QString

主窗口.h

....
void setFoo(const QString & text);

主窗口.cpp

...
void MainWindow::setFoo(const QString & text) {
    ui->fooLabel->setText(text);
}

最后我们建立联系:

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w1;
    SecondWindow w2;

    QObject::connect(&w2, &SecondWindow::messageChanged, &w1, &MainWindow::setFoo); 

    w1.show();
    w2.show();

    return a.exec();
}

更新:

void MainWindow::keyPressEvent(QKeyEvent *event) {
    switch (event->key()) {
        case Qt::Key_A:
        if (event->modifiers()==Qt::ShiftModifier) {
            SecondWindow*secwind= new SecondWindow();
            connect(secwind, &SecondWindow::messageChanged, this, &MainWindow::setFoo);
            secwind->show();
        }
        break;
    }
}

推荐阅读