恢复插槽参数

时间:2018-03-28 18:17:59

标签: c++ qt

我有一个接收QString的插槽,我想在另一个变量中为此参数赋值,或者直接在同一个类的另一个方法中使用它。

信号是从其他一些班级发出的。

MyWidget.h

#ifndef MYWIDGET_H
#define MYWIDGET_H
#include"myclass.h"
#include <QWidget>
#include <QtWidgets>
namespace Ui {
class MyWidget;
}

class MyWidget : public QWidget
{
    Q_OBJECT

public:
    explicit MyWidget(QWidget *parent = 0);
    ~MyWidget();
private:
    Ui::MyWidget *ui;
signals:
   void redirectData(QString data);
public slots:
   void sendData();
private:
   MyClass *myClass; // the object to receive and output the data
};

#endif // MYWIDGET_H

MyWidget.cpp

#include "mywidget.h"
#include "ui_mywidget.h"
MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);
    myClass = new MyClass();
    connect(ui->pushButton, SIGNAL(clicked()), this, SLOT(sendData()));
    connect(this, SIGNAL(redirectData(QString)), myClass, SLOT(outputData(QString)));
}

MyWidget::~MyWidget()
{
    delete ui;
}
void MyWidget::sendData()
{

    emit redirectData(ui->lineEdit->text());
    myClass->show();

}

MyClass.h

#ifndef MYCLASS_H
#define MYCLASS_H
#include <QWidget>

namespace Ui {
class MyClass;
}

class MyClass : public QWidget
{
    Q_OBJECT

public:
    explicit MyClass(QWidget *parent = 0);
    ~MyClass();
    QString x;
private:
    Ui::MyClass *ui;
signals:
    void send2(QString);
public slots:
    void outputData(QString data);
};
#endif // MYCLASS_H

MyClass.cpp

#include "myclass.h"
#include "ui_myclass.h"

MyClass::MyClass(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyClass)
{
    ui->setupUi(this);
    ui->plainTextEdit->insertPlainText(x); // show x in plainTextEdit
}

MyClass::~MyClass()
{
    delete ui;
}
void MyClass::outputData(QString data){

   x=data; // affect data a x 
}

screenshot 1

我想在x中显示QPlainTextEdit的值。

此方法是正确的,但不适合我的其余代码。我想保留x中的值。

  

MyClass.cpp

#include "myclass.h"
#include "ui_myclass.h"

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

MyClass::~MyClass()
{
    delete ui;
}
void MyClass::outputData(QString data){
    ui->plainTextEdit->insertPlainText(data); 
}

screenshot 2

1 个答案:

答案 0 :(得分:0)

现在这是一个好问题,如果有点罗嗦和基本。它显然大部分是完整的(.ui文件丢失了 - 但不包括它们!)并且可以重现。 因此,您可以做两件事:

  1. 只需在插槽中设置纯文本编辑的值:

    void MyClass::outputData(QString data){
      x = data;
      ui->plainTextEdit->insertPlainText(x);
    }
    

    如果您不想在x中的任何其他位置使用该值,则根本不需要将值存储在MyClass中。

  2. 如果MyClass应公开x属性以与其他类进行交互,则应该这样做 - 然后使用通知信号修改小部件:

    class MyClass : public QWidget {
        Q_OBJECT
        Q_PROPERTY(QString x READ x WRITE setX NOTIFY xChanged)
        QString m_x;
        Ui::MyClass *ui;
    public:
        explicit MyClass(QWidget *parent = {}) {
          ui->setupUi(this);
          connect(this, &MyClass::xChanged, ui->plainTextEdit, &QPlainTextEdit::insertPlainText);
        ~MyClass {}
        Q_SIGNAL void xChanged(const QString &);
        Q_SLOT void setX(const QString &x) {
          if (m_x != x) {
            m_x = x;
            emit xChanged(m_x);
          }
        }
        QString x() const { return m_x; }
    };
    
  3. 其他说明

    1. MyClass::x成员不应公开。

    2. 作为方法参数传递的容器应该几乎总是一个const引用类型 - 以避免过早地使传递对象的副本失望。因此,您应该按如下方式修改签名 - 在声明(头文件)和定义(实现 - .cpp文件)中:

      void MyClass::send2(const QString&);
      void MyClass::outputData(const QString &data)
      void MyWidget::redirectData(const QString &data)
      

      您使用的旧式connect语法要求规范化签名并且不会更改 - 必须删除const和引用。

    3. 没有必要通过指针存储ui - 只需按值存储即可。然后,C ++语言会自动为您处理内存管理,默认的编译器生成的析构函数可以完成这项任务。

    4. 在自包含的示例中,无需使用.ui文件。手动创建小部件并将其布置是非常简单的,如下所示。

    5. 重做的例子

      考虑到所有这些,这将是一个独立的演示 - 不需要Ui文件。您的问题应该包含这样的内容 - 它是自包含的单个文件。不希望使用属性来表示意图:这些是类的可变属性。

      #include <QtWidgets>
      
      class Source : public QWidget {
         Q_OBJECT
         Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
         QHBoxLayout m_layout{this};
         QLineEdit m_edit;
         QPushButton m_send{tr("Send")};
         QString m_text;
      public:
         Source(QWidget *parent = {}) : QWidget(parent) {
            m_layout.addWidget(&m_edit);
            m_layout.addWidget(&m_send);
            connect(&m_send, &QPushButton::clicked, [this]{
               setText(m_edit.text());
            });
         }
         Q_SLOT void setText(const QString &text) {
            if (text == m_text) return;
            m_text = text;
            emit textChanged(m_text);
         }
         QString text() const { return m_text; }
         Q_SIGNAL void textChanged(const QString &);
      };
      
      class Destination : public QWidget {
         Q_OBJECT
         Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged)
         QHBoxLayout m_layout{this};
         QPlainTextEdit m_edit;
         QString m_text;
      public:
         Destination(QWidget *parent = {}) : QWidget(parent) {
            m_layout.addWidget(&m_edit);
            connect(this, &Destination::textChanged, &m_edit, &QPlainTextEdit::setPlainText);
         }
         Q_SLOT void setText(const QString &text) {
            if (text == m_text) return;
            m_text = text;
            emit textChanged(m_text);
         }
         QString text() const { return m_text; }
         Q_SIGNAL void textChanged(const QString &);
      };
      
      int main(int argc, char **argv) {
         QApplication app{argc, argv};
         Source src;
         Destination dst;
         QObject::connect(&src, &Source::textChanged, &dst, [&](const QString &text){
            if (!dst.isVisible()) {
               dst.move(src.frameGeometry().topRight()); // align the windows
               dst.show();
            }
            dst.setText(text);
         });
         src.show();
         return app.exec();
      }
      
      #include "main.moc"