QT 狡猾与邮件客户端

QT Cuncurrent With mail Client

本文关键字:客户端 QT      更新时间:2023-10-16

嗨,我已经在这里问了我的问题并理解了为什么它不起作用,现在我已经通过将 Smptp 对象作为类变量来修改源代码,但仍然不起作用。

我需要实现的是从我选择QtConcurrent::run()执行此操作的线程发送邮件,但在单击发送按钮后未调用插槽。

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "QSettings"
#include "QFuture"
#include "QtConcurrent/QtConcurrent"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->sendBtn, SIGNAL(clicked()),this, SLOT(test()));
    connect(ui->exitBtn, SIGNAL(clicked()),this, SLOT(close()));
    connect(ui->browseBtn, SIGNAL(clicked()), this, SLOT(browse()));
}
void MainWindow::browse()
{
    files.clear();
    QFileDialog dialog(this);
    dialog.setDirectory(QDir::homePath());
    dialog.setFileMode(QFileDialog::ExistingFiles);
    if (dialog.exec())
        files = dialog.selectedFiles();
    QString fileListString;
    foreach(QString file, files)
        fileListString.append( """ + QFileInfo(file).fileName() + "" " );
    ui->file->setText( fileListString );
}
void MainWindow::test(){

    QFuture<void> f4 = QtConcurrent::run(this,&MainWindow::sendMail); // this not work
    //sendMail(); // this works
}



void MainWindow::sendMail()
{
    smtp = new Smtp(ui->uname->text(), ui->paswd->text(), ui->server->text(), ui->port->text().toInt());
    connect(smtp, SIGNAL(status(QString)), this, SLOT(mailSent(QString)));
    if( !files.isEmpty() )
        smtp->sendMail(ui->uname->text(), ui->rcpt->text() , ui->subject->text(),ui->msg->toPlainText(), files );
    else
        smtp->sendMail(ui->uname->text(), ui->rcpt->text() , ui->subject->text(),ui->msg->toPlainText());

}
void MainWindow::mailSent(QString status)
{
    if(status == "Message sent")
        QMessageBox::warning( 0, tr( "Qt Simple SMTP client" ), tr( "Message sent!nn" ) );
    delete smtp;
}
MainWindow::~MainWindow()
{
    delete ui;
}

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "smtp.h"
#include <QtWidgets/QMessageBox>
#include <QFileDialog>
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void sendMail();
    void mailSent(QString);
    void browse();
    void test();
private:
    Ui::MainWindow *ui;
    QStringList files;
    Smtp* smtp ;
};
#endif // MAINWINDOW_H

如果我直接调用sendMail();它可以工作,但使用QFuture<void> f4 = QtConcurrent::run(this,&MainWindow::sendMail);它不起作用,不工作意味着插槽没有被调用,我该如何解决这个问题?

我从这里引用代码 https://github.com/xcoder123/SimpleSmtp_SSL_QT5/tree/master/smtp_attachements

谢谢哈里斯

我已经在这里提到的解决方案是使用 QThread 而不是 QtConcurrent::run .Qt文档中包含一个详细的例子:http://doc.qt.io/qt-5/qthread.html#details

以下代码使此示例适应您的用例。 smtp被移动到workerThread。主线程和workerThread之间的通信是使用信号和插槽完成的。请注意,您不能再在Smtp中调用任何与GUI相关的函数(例如显示消息框等(!这必须在主线程中完成。

用户名、密码等可能也应该通过信号传递给Smtp::sendMail

主窗口.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QtWidgets/QMessageBox>
#include <QFileDialog>
#include <QThread>
namespace Ui {
class MainWindow;
}
class Smtp;
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
    ~MainWindow();
private slots:
    void sendMailButtonClicked();
    void mailSent(QString);
    void browse();
private:
    Ui::MainWindow *ui;
    QStringList files;
    Smtp* smtp;
    QThread workerThread;
signals:
    void sendMail(const QString &from, const QString &to, const QString &subject, const QString &body, QStringList files);
};
#endif // MAINWINDOW_H

主窗口.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "smtp.h"
MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    connect(ui->sendBtn, SIGNAL(clicked()),this, SLOT(sendMailButtonClicked()));
    connect(ui->exitBtn, SIGNAL(clicked()),this, SLOT(close()));
    connect(ui->browseBtn, SIGNAL(clicked()), this, SLOT(browse()));
    smtp = new Smtp(ui->uname->text(), ui->paswd->text(), ui->server->text(), ui->port->text().toInt());
    smtp->moveToThread(&workerThread);
    connect(this, SIGNAL(sendMail(QString,QString,QString,QString,QStringList)), smtp, SLOT(sendMail(QString,QString,QString,QString,QStringList)));
    connect(smtp, SIGNAL(status(QString)), this, SLOT(mailSent(QString)));
    workerThread.start();
}
void MainWindow::browse()
{
    files.clear();
    QFileDialog dialog(this);
    dialog.setDirectory(QDir::homePath());
    dialog.setFileMode(QFileDialog::ExistingFiles);
    if (dialog.exec())
        files = dialog.selectedFiles();
    QString fileListString;
    foreach(QString file, files)
        fileListString.append( """ + QFileInfo(file).fileName() + "" " );
    ui->file->setText( fileListString );
}
void MainWindow::mailSent(QString status)
{
    if(status == "Message sent")
        QMessageBox::warning( 0, tr( "Qt Simple SMTP client" ), tr( "Message sent!nn" ) );
}
MainWindow::~MainWindow()
{
    workerThread.quit();
    workerThread.wait();
    delete ui;
}
void MainWindow::sendMailButtonClicked()
{
    emit sendMail(ui->uname->text(), ui->rcpt->text() , ui->subject->text(),ui->msg->toPlainText(), files );
}

smtp.h 中:将sendMail设置为插槽:

public slots:
    void sendMail( const QString &from, const QString &to,
                   const QString &subject, const QString &body,
                   QStringList files = QStringList());