首页 > 解决方案 > 如何从 _clicked() 事件中发出另一个实例的信号?

问题描述

可运行项目在这里:在此处 输入链接描述


我真诚地很高兴得到您的详细答案来解决这个问题,但我仍然对这个问题感到困惑:

案例1:更改socket_session为主窗口的成员变量

class MainWindow : public QMainWindow
{
    Q_OBJECT

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

    SocketThread* socket_session;

private:
...

但这不是 access 的解决方案setFlag,即使我像这样更改了 `Form1::on_qpushButton__set_white_level_0_clicked()' 函数:

void Form1::on_qpushButton__set_white_level_0_clicked() {
    qDebug() <<"clicked()";
    socket_session->setThreadFlag(true);

}

仍然没有意义,因为form1instance 没有socket_threadmainwindow. 我认为有一个解决方案是创建另一个类,其中包含我想从内部使用的所有实例,mainwindow但我认为这不是一个好方法,因为我正在使用线程并访问一个包含所有实例的全局大实例类对于像我这样的人来说,“共享”不是一个好主意。

#include <form1.h>
#include <ui_form1.h>
#include "socketthread.h"


Form1::Form1(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Form1) {

    ui->setupUi(this);
}

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

void Form1::on_qpushButton__set_white_level_0_clicked() {
    qDebug() <<"clicked()";
    socket_session->setThreadFlag(true);

}

在此处输入图像描述

我知道我对此缺乏了解,但是,我想做一些没人做的事情吗……?我认为每个人都希望清楚地分离所有对象及其方法,并通过信号或从交付的对象实例调用函数进行通信......

案例2:......让我先试试你建议的方法......


我可以阅读 C++ 代码和整体结构,但我不知道为什么我必须为此挣扎,所以请帮助我,亲爱的 Guru。

在 socketthread.h 上:

class SocketThread : public QThread {

    Q_OBJECT

public:

    QTcpSocket *socket_session;

    SocketThread();
    ~SocketThread(){}

    bool connectToServer(QString, int);
    void sendData(const char*, int, int);
    void run(void);

private:
    QString message;
    volatile bool threadFlag;

signals:
    void changedThreadFlag(void);
    void changedMessageStr(void);
    void setThreadFlag(bool);
    void setMessageStr(QString);

private slots:
    void setStr(QString);
    void setFlag(bool);
    void socketError(QAbstractSocket::SocketError);

};

它的实现是......

SocketThread::SocketThread() {
    socket_session = NULL;
    threadFlag = false;
    message = "NULL";

    connect(this, SIGNAL(setThreadFlag(bool)), this, SLOT(setFlag(bool)));

}

...

void SocketThread::setStr(QString str) {
    message = str;
}

void SocketThread::setFlag(bool flag) {
    threadFlag = flag;
}


void SocketThread::run() {
    while(true) {
        if(threadFlag) {
            QThread::msleep(100);
            qDebug() << message;
        } else
            break;
    }
    qDebug() << "loop ended";
}

我有一个带有按钮的表单,我像这样放置了一个 clicked() 插槽...

按钮的名称


void Form1::on_qpushButton__set_white_level_0_clicked() {
    qDebug() <<"clicked()";
    --how can I emit the signal of the one of socketthread from here??
}

现在,主窗口是这样的:


MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow) {

    QString addr_server = "223.194.32.106";
    int port = 11000;
    SocketThread* socket_session = new SocketThread();
    socket_session->connectToServer(addr_server, port);


    ui->setupUi(this);
    Form1* form1;
    form1 = new Form1();

    ui->stackedWidget_mainwindow->addWidget(form1);

    ui->stackedWidget_mainwindow->setCurrentWidget(form1);

    socket_session->run();

...

我只是想从 QPushbutton_clicked() 插槽内部发出 socketthread 的信号 setThreadFlag。一旦socket_session->run()开始,我需要通过从正在运行的线程threadFlag发出一个按钮来更改按钮。setThreadFlag()而我只是困在这里。

甚至可能吗?还是我从一开始就做错了?

标签: c++multithreadingqtsignalsslot

解决方案


正如这篇文章中提到的:

“发出信号” == “调用函数”

所以你真正要做的就是调用信号函数,所有连接的插槽都应该被调用。

这当然意味着Form1对象需要一个指向线程对象的指针,即它需要一个socket_session. 然后你可以简单地调用对象上的信号

socket_session->setThreadFlag(your_flag);

当然,如果Form1socket_session指针的副本,还不如setFlag直接调用,如果是public.


推荐阅读