Qt pop3接收邮件并下载附件程序

  1. 功能简介:帮朋友做的自动登陆邮箱接收邮件,并把邮件保存到数据库,附件下载到工程目录。
  2. 环境:qtcreator5.4,MSVC2013-Opengl,数据库:mysql
  3. 用到的第三方库https://github.com/dbzhang800/QtMail.git
  4. 界面
  5. 源码:Qt pop3接收邮件并下载附件程序
  6. 主要代码
  • 创建数据库并初始化显示

 

 ui->setupUi(this);
    ui->loginButton->setEnabled(true);
    ui->logoffButton->setEnabled(false);
    ui->updateButton->setEnabled(false);
    ui->updateButton->hide();//没找到可以用这个的命令,暂时屏蔽掉
    ui->labelLoading->hide();
    m_mailCount=0;
    m_loadedCount=0;

    m_db=QSqlDatabase::addDatabase("QMYSQL");
    m_db.setHostName("localhost");
    m_db.setPort(3306);
    m_db.setUserName("root");
    m_db.setPassword("root123");//根据mysql的实际情况设定用户名和密码

    if(!m_db.open())
    {
        QMessageBox::critical(this,tr("Error"),tr("open data base failed"));
        qDebug()<<"1:"<<m_db.lastError();
        return;
    }
    QSqlQuery query(m_db);
    if(!query.exec("create database if not exists maildb default charset=utf8"))
    {
        QMessageBox::critical(this,tr("Error"),tr("create data base maildb failed"));
        qDebug()<<"2:"<<query.lastError();
        return;
    }
    //指定数据库编码
    if(!query.exec("set names utf8 "))
    {
        QMessageBox::critical(this,tr("Error"),tr("set database encode failed"));
        qDebug()<<"4:"<<query.lastError();
        return;
    }

    query.exec("use maildb");
    if(!query.exec("create table if not exists mailtable(mailindex int auto_increment primary key,subject varchar(128),sender varchar(128),content varchar(1024),attchment varchar(128),time varchar(64))default charset=utf8 auto_increment=1"))
    {
        QMessageBox::critical(this,tr("Error"),tr("create table mailtable failed"));
        qDebug()<<"3:"<<query.lastError();
        return;
    }

    m_dbmodel = new QSqlTableModel(this,m_db);
    m_dbmodel->setTable("mailtable");
    // 设置编辑策略
    m_dbmodel->setEditStrategy(QSqlTableModel::OnManualSubmit);
    ui->mailTableView->setModel(m_dbmodel);
    m_dbmodel->select();

    m_pop = new QxtPop3(this);
    m_pop->sslSocket()->setProtocol(QSsl::TlsV1_0);
    m_pop->sslSocket()->setPeerVerifyMode(QSslSocket::QueryPeer);

    connect(m_pop, SIGNAL(disconnected()), this, SLOT(disconnected()));
    connect(m_pop, SIGNAL(connected()), this, SLOT(connected()));

 

 

  • 登陆
void MainWindow::on_loginButton_clicked()
{
    QString hostname = ui->serverEdit->text();
    int port = ui->portEdit->text().toInt();
    QString username = ui->userEdit->text();
    QString pass = ui->pawEdit->text();
    m_pop->setUsername(username.toLocal8Bit());
    m_pop->setPassword(pass.toLocal8Bit());
    m_pop->setStartTlsDisabled(true);
    m_pop->connectToHost(hostname.toLocal8Bit(), port);

}

发送list命令和retry命令获取邮件

//在update函数中发送list命令
void MainWindow::updateData()
{
    ui->labelLoading->show();
    m_mailCount=0;
    m_loadedCount=0;
    if (!m_pop->isConnected()) return;

    QxtPop3Reply* reply = m_pop->messageList();
    connect(reply, SIGNAL(finished(int)), this, SLOT(handleList(int)));
    qDebug()<<"LIST sent";

}
//在槽函数中处理list的返回结果,逐条发送retry命令
void MainWindow::handleList(int code)
{
    switch (code)
    {
        case QxtPop3Reply::OK:
            qDebug()<<"LIST: OK received";
            {
                QxtPop3ListReply* reply = dynamic_cast<QxtPop3ListReply*>(sender());
                if (reply == 0)
                {
                    QMessageBox::critical(this,tr("warning"),tr("MainWindow::handleList: sender is not a QxtPop3ListReply"));
                    return;
                }
                m_mailCount= reply->list().size();
                foreach (QxtPop3Reply::MessageInfo msginfo, reply->list())
                {
                    qDebug()<<QString("message %1: %2 bytes").arg(msginfo.id).arg(msginfo.size);
                    //通过retry命令获得详情
                    QxtPop3Reply* reply = m_pop->retrieveMessage(msginfo.id);
                    connect(reply, SIGNAL(finished(int)), this, SLOT(handleRetr(int)));
                    qDebug()<<"RETR sent";
                }
            }
            break;
        case QxtPop3Reply::Aborted:
            qDebug()<<"LIST aborted.";
            break;
        case QxtPop3Reply::Timeout:
            qDebug()<<"LIST: time out.";
            break;
        default:
            break;
    }
}
//在槽函数中处理retry命令的返回结果,得到邮件的各部分内容,并保存附件
void MainWindow::handleRetr(int code)
{
    switch (code)
    {
    case QxtPop3Reply::OK:
        qDebug()<<"RETR: OK received";
        {
            QxtPop3RetrReply* reply = dynamic_cast<QxtPop3RetrReply *>(sender());
            if (reply == 0)
            {
                QMessageBox::critical(this,tr("warning"),tr("MainWindow::handleRetr: sender is not a QxtPop3RetrReply"));
                return;
            }
            if (m_msg!=NULL)
            {
                delete m_msg;
                m_msg=NULL;
            }

            m_msg = reply->message();

             //headers;
            QHash<QString, QString> headers=m_msg->extraHeaders();
            //判断改封邮件是否已经在数据库中
            QSqlQuery query(m_db);
            query.prepare("select * from mailtable where time=?");
            query.addBindValue(headers["date"]);
            if(!query.exec())
            {
                 qDebug()<<"4:"<<query.lastError();
                 break;//sql语句执行错误,break
            }
            if(query.size()>0)
               break;      //数据库中已经有该条记录,break
             if(!query.exec("select * from mailtable"))
             {
                 qDebug()<<"5:"<<query.lastError();
                 break;//sql语句执行错误,break
             }

            QString subject=headers["subject"].toUtf8();
            QString sender=headers["from"].toUtf8();
            QString date=headers["date"].toUtf8();
            QString body=m_msg->body();
            QString content=mailContent(body).toUtf8();
            QString attachment=NULL;
            //attachment
            if (m_msg->attachments().size() > 0)
            {
                //如果路径不存在创建路径
                QString dirPath=QString("attchments/%1-%2").arg(query.size()+1).arg(subject);//attachments/1-subject/attachmentFile
                QDir dir;
                QString currentDir = dir.currentPath();//保存当前工作路径
                if(!dir.exists(dirPath))
                    dir.mkpath(dirPath);
                dir.setCurrent(dirPath);//更改执行路径
                foreach(QString filename, m_msg->attachments().keys())
                {
                    attachment.append(filename);
                    attachment.append(",");
                    //保存附件
                    QxtMailAttachment att = m_msg->attachment(filename);
                    QFile file(filename);
                    QIODevice::OpenMode flags = QIODevice::WriteOnly;
                    if (att.isText())
                        flags |= QIODevice::Text;
                    if(!file.open(flags))
                    {
                         qDebug()<<"6:"<<"save "<<filename<<" failed";
                         continue;
                    }
                    file.write(att.rawData());
                    file.close();
                }
                dir.setCurrent(currentDir);//恢复工作路径
                attachment = attachment.left(attachment.length() - 1);//去掉最后的分号
            }
            attachment=attachment.toUtf8();
            //保存到数据库
            query.clear();
            query.prepare("insert into mailtable(mailindex,subject,sender,content,attchment,time) values(?,?,?,?,?,?)");
            query.addBindValue(0);
            query.addBindValue(subject);
            query.addBindValue(sender);
            query.addBindValue(content);
            query.addBindValue(attachment);
            query.addBindValue(date);
            if(!query.exec())
            {
                QMessageBox::critical(this,tr("Error"),tr("insert data failed"));
                qDebug()<<"5:"<<query.lastError();
            }
            m_dbmodel->select();
        }
        break;
    case QxtPop3Reply::Aborted:
        qDebug()<<"RETR aborted.";
        break;
    case QxtPop3Reply::Timeout:
        qDebug()<<"RETR: time out.";
        break;
    default:
        break;
    }
    m_loadedCount++;
    if(m_loadedCount==m_mailCount)
        ui->labelLoading->hide();
}
  • 退出登陆
void MainWindow::on_logoffButton_clicked()
{
    if(m_pop!=NULL)
    {
        m_pop->quit();
        m_pop->disconnect();
        ui->loginButton->setEnabled(true);
        ui->logoffButton->setEnabled(false);
    }
}
  • 运行结果如下图

  • 程序界面
  • 下载的附件

  • 注意事项:

1、因为使用的是pop3命令,要在邮箱设置-》POP3/SMTP/IMAP开启POP3/SMTP和POP3/IMAP

2、安装mysql,并启动mysql服务。拷贝C:\Program Files (x86)\MySQL\MySQL Server 5.5\lib\libmysql.dll到C:\Qt\Qt5.4.0\5.4\msvc2013_opengl\bin,不然会出现数据库驱动没有加载的编译错误

3、只能接收开通POP3/SMTP和POP3/IMAP之后接收的邮件,之前的接收不到。

4、163邮箱以及qq企业邮箱测试ok,126邮箱和qq普通邮箱发完list命令后没收到返回,不知道原因

 

 

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值