【问题标题】:Connecting to a same signal in two windows在两个窗口中连接到相同的信号
【发布时间】:2020-03-29 11:41:42
【问题描述】:

你能想出第二种情况不起作用的原因吗?

我在两个窗口有信号连接,SettingsPatients

Settings:

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

connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler);
...
}

api 是一个类的全局实例。

Patients:

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

connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);

}

情况 1 - 工作

我从Main 构造SettingsPatients 窗口

#include <QApplication>

tetra_grip_api api;

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    api.openSerialPort();
    QObject::connect(api.serial, SIGNAL(readyRead()), &api, SLOT(readData()));


    Settings  w(nullptr); //---->this behaves right
    Patients  v(nullptr); //---- >this behaves right

    v.show();
    w.show();

    return a.exec();
}

我的意思是,两个插槽都被调用,QLabel 相应地设置文本

情况 2 - 不工作

我从Settings 拨打Patients

void Settings::on_pushButton_patients_clicked()
{
    this->close();
    stagetwo = new Patients(this);
    stagetwo -> show();
}

stagetwo 是公开的

public:
     Settings(QString,QWidget *parent = nullptr);
    ~Settings();
     Patients *stagetwo;

这里Settings 工作正常(插槽被调用)但Patients::eventhandlerTwo 根本没有被调用。

编辑(发现错误)

了解我需要在 API (battery_percentage) 中调用一个方法来发出信号 tetraGripEvent 为时已晚(bettery_percentage 将联系设备中的“电池寄存器”,这将强制 API 发出信号)

基本上我需要在SettingsPatients 上都这样做

#include "settings.h"
#include "ui_settings.h"

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

    connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler);
...
  tetra_grip_api::battery_percentage(); ------> calling this only emit the signal

}

Patients

#include "patients.h"
#include "ui_patients.h"

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


  connect(&api, &tetra_grip_api::tetraGripEvent,this, &Patients::eventHandlerTwo);
...
  tetra_grip_api::battery_percentage(); 

}

【问题讨论】:

  • 您的Settings 类型是否设置了Qt::WA_DeleteOnClose 属性?
  • 看这里:github.com/bialasjaroslaw/event_handlers 如果您单击按钮并打开第二个窗口,则会处理两个事件,因为创建了患者类的对象。如果您没有在 5 秒内单击(事件是 QTimer 的超时),则不会创建患者对象,尽管从未连接到事件信号。基本上没有病人类的对象连接到 QTimer::timeout,所以除了 Settings::eventHandler 之外什么都没有被触发。在您的第一个示例中,两个对象都是在开始时创建的,因此从一开始就是连接的。

标签: c++ qt


【解决方案1】:

根据QWidget::close() 的 Qt 文档,QMainWindow 继承自:

QApplication::lastWindowClosed() 信号在最后一次发出时发出 可见的主窗口(即没有父窗口的窗口) Qt::WA_QuitOnClose 属性 设置已关闭。 默认这个属性 为除了瞬态窗口之外的所有小部件设置,例如飞溅 屏幕、工具窗口和弹出菜单。

因此,在第二种情况下,当您将 Patients 的父级设置为 Settings 实例时,您应该会遇到这样的未定义行为。因为通过调用Settings::close() 应该删除Settings 并在调用返回到事件循环时退出应用程序。您可以通过以下方式显式更改它:

Settings::Settings( QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Settings)
{
    ui->setupUi(this);
    this->setAttribute(Qt::WA_QuitOnClose, false);
    connect(&api, &tetra_grip_api::tetraGripEvent,this, &Settings::eventHandler);
...
}

您还可以将两个窗口重新设置为另一个窗口。

【讨论】:

  • 感谢您的意见。 this-&gt;setWindowFlag(Qt::WA_QuitOnClose, false); 抛出一个错误说 error: cannot initialize a parameter of type 'Qt::WindowType' with an rvalue of type 'Qt::WidgetAttribute' qwidget.h:569:38: note: passing argument to parameter here
猜你喜欢
  • 2013-09-21
  • 1970-01-01
  • 2018-07-27
  • 1970-01-01
  • 1970-01-01
  • 2020-05-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多