在Qt中通过信号和插槽系统传递变量[关闭]

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了在Qt中通过信号和插槽系统传递变量[关闭]相关的知识,希望对你有一定的参考价值。

所以我想通过Qt中的信号和插槽系统传递一个std :: string变量;我在堆上有一个名为RecordTalks的类,当收到来自聊天的消息超过25个符号时,它会发出一个信号。代码如下:

#include "recordtalks.h"

// records chat to files RecordTalks::RecordTalks(QObject *parent) {

}

RecordTalks::~RecordTalks() {
    std::cout << "destructor" << "
"; }

void RecordTalks::run(QString data) {
    std::cout << ">>> whole data is: " << data.toStdString() <<  " ------------------
";
    std::string text = data.toStdString();

    extractNick(text);
    extractRoom(text);
    //std::cout << "save in recordTalks is: " << save << "
";
    if((nick.size()!=0 && room.size()!=0))
    {
        extractText(data);
        pushToVector(removeDigitsAndSpecials(nick), subText);
    }
    else
       return; }

void RecordTalks::run() {
    save=false;
    save = console.saveNowState();
    if(save==true)
    {
        saveToFile(allTexts, "BOT"); //trigger line saving to file
        file.close();
        removeDuplicatedNicks();
        createNickFiles(nicks_v);
        match_nicks_and_allTexts(allTexts);
        closeNickFiles();

        nicks_v.clear();
        nickAndFile_pair_vec.clear();
        text.clear();
        allTexts.clear();
        nick.clear();
        room.clear();
        subText.clear();
        save=false;
    } 
}

void RecordTalks::extractText(QString &data) {
    std::string text = data.toStdString(); // tu zmiana
    size_t pos, pos2;

    if((pos=text.find("PRIVMSG #"))!=std::string::npos)
    {
        if((pos2=text.find(":",pos))!=std::string::npos)
        {
            subText = text.substr(pos2+1, text.size()-(pos2+1)  );
            if((pos=subText.find("u0001ACTION "))!=std::string::npos)
            {
                subText = subText.substr(pos+8 , subText.size()-3-(pos+8));
            }
            else
                std::cout << "subText: " << subText  << "
";
         }
    }
    else  //if nothing to write to log:
    {
        return ;
    } 
}

void RecordTalks::extractNick(std::string &text) {
    Extract_NickAndRoom e;
    QString temp = QString::fromStdString(text);
    nick = e.extractNick(temp);
    //std::cout << "nick is: " << nick << "
";

}

void RecordTalks::extractRoom(std::string &text) {
    Extract_NickAndRoom e;
    QString temp = QString::fromStdString(text);
    room = e.extractRoom(temp);
    //std::cout << "room is: " << room << "
"; }


void RecordTalks::pushToVector(std::string nick, std::string &subText)
//general vector with texts {
    if(subText.size()>25 ) //if line of text from irc is bigger than 25 signs
    {
        std::pair<std::string, std::string> para = std::make_pair(nick, subText);
        allTexts.push_back(para);  // pair --> vector


        emit textUpdateSignal(subText);
        std::cout << "EMITTTTTTTTTTTTTTTTTTT " << "
";
        //std::cout << ">>> subText: " << subText << "  nick: " << nick << " <<<" << "
";
    }

    if(allTexts.size()==60)
    {
        saveToFile(allTexts, "BOT"); //trigger line saving to file
        file.close();
        removeDuplicatedNicks();
        createNickFiles(nicks_v);
        match_nicks_and_allTexts(allTexts);
        closeNickFiles();

        nicks_v.clear();
        nickAndFile_pair_vec.clear();
        text.clear();
        allTexts.clear();
        nick.clear();
        room.clear();
        subText.clear();
        save=false;
    } 
}

void RecordTalks::saveToFile( std::vector< std::pair<std::string,
std::string> > &allTexts, std::string nickFileName) {
    std::string address = "D:\Qt_workspace\weatherBot\logs\" + nickFileName + ".txt";
    file.open(address, std::ios::out | std::ios::app);

    for (int i = 0; i < allTexts.size(); ++i)
    {
        file << allTexts[i].second; //writes text to file, not the nicks
    } 
}




void RecordTalks::createNickFiles(std::vector<std::string> &nicks_v) {
   /* make vector of pair nick and file, so we can identify the file name and then
       put text-matching-to-file-nick with file name */
    for (int i = 0; i < nicks_v.size(); ++i)
    {
        std::fstream file2("D:\Qt_workspace\weatherBot\logs\"+ nicks_v[i] + ".txt",
                           std::ios::out | std::ios::app);
        std::pair<std::string, std::fstream> nickAndFile_pair;
        nickAndFile_pair = std::make_pair(removeDigitsAndSpecials(nicks_v[i]),
                                          std::move(file2));
        nickAndFile_pair_vec.push_back(std::move(nickAndFile_pair));
    } 
}// nicks_v[i] put inside function removeDigitsAndSpecials(std::string& nick)


void RecordTalks::match_nicks_and_allTexts(std::vector<
std::pair<std::string, std::string> > allTexts) {
    for (int i = 0; i < nickAndFile_pair_vec.size(); ++i)
    {
        for (int j = 0; j < allTexts.size(); ++j)
        {
            if(nickAndFile_pair_vec[i].first == allTexts[j].first)
            {
                nickAndFile_pair_vec[i].second << allTexts[j].second;
                //nickAndFile_pair_vec[j].second.flush();
            }
        }
    }

    std::cout << "allTexts size in match_nicks_and_allTexts is: ";
    std::cout << allTexts.size() << "
"; 
}


void RecordTalks::removeDuplicatedNicks() {
    std::vector< std::pair<std::string, std::string> > temp = allTexts;
    std::cout << "temp size: " << temp.size() << "
";

    for (int i = 0; i < temp.size(); ++i)
    {
        for (int j = i+1; j < temp.size(); ++j)
        {
            if(temp[i].first == temp[j].first  &&  i+1< temp.size())
            {
                temp.erase(temp.begin()+j);
                j--;
            }
        }
    }


    for (int i = 0; i < temp.size(); ++i)
    {
        nicks_v.push_back(temp[i].first);
    }
    std::cout << "nicks_v.size: " << nicks_v.size() << "
";

}

void RecordTalks::closeNickFiles() //closes separate nick files {
    for (int i = 0; i < nickAndFile_pair_vec.size(); ++i)
    {
        nickAndFile_pair_vec[i].second.close();
    }
    std::cout << "Files closed..." << "
"; }


std::string RecordTalks::removeDigitsAndSpecials(std::string& nick) {
    for (int i = 0; i < nick.size(); ++i)
    {
        if(std::isalpha(nick[i]))
        {

        }

        else if(std::isdigit(nick[i]))
        {
             nick.erase(nick.begin()+i);
             std::cout << "removing: " << nick[i] << "
";
             i--;
        }
        else
        {
            nick.erase(nick.begin()+i);
            std::cout << "removing: " << nick[i] << "
";
            i--;
        }
    }
    return nick; 
}

然后在另一个类我有连接功能。当我用这种形式写它:

connect(recordTalks, &RecordTalks::textUpdateSignal, this, &Socket::updateDatabaseSLOT); 

插槽接收信号。但是当我以这种方式编写函数时:

connect(recordTalks, SIGNAL(textUpdateSign(std::string)), this, 
        SLOT(updateDatabaseSLOT(std::string)));

插槽没有被解雇。所以我的问题是,原因是什么。在其他情况下,后一版本工作得很好。

插槽看起来像这样:

void Socket::updateDatabaseSLOT(std::string textUpdate)
{
    std::cout << "updates text: << textUpdate << "
";

     database.push_back(textUpdate);
}
答案

我认为你的连接声明中有拼写错误。 Qt可能会令人沮丧。 SIGNAL(textUpdateSign(std::string )应该是SIGNAL(textUpdateSignal(std::string )

以上是关于在Qt中通过信号和插槽系统传递变量[关闭]的主要内容,如果未能解决你的问题,请参考以下文章

C++ 和 QT4.5 - 传递 const int& 过大?通过引用传递是不是有助于信号/插槽?

Qt - 使用信号/插槽关闭子菜单

Qt连接两个信号和一个插槽

使用 qt 中的信号/插槽更新 gui [关闭]

如果堆分配的对象被销毁并重新分配指针,Qt 的信号和插槽系统会工作吗?

详解 Qt 线程间共享数据(使用signal/slot传递数据,线程间传递信号会立刻返回,但也可通过connect改变)