Qt插槽未激活

时间:2019-03-07 23:07:37

标签: c++ qt

所以我有2个类,一个名为ConsoleInput,包含成员函数check4Flood,第二个名为AntiFloodSys,其中存在用于信号插槽系统的连接功能,以及其信号(QTimer)和插槽。 AntiFloodSys对象位于check4Flood成员函数中,该函数的作用域永无止境,因为内部存在无限的while循环。因此,该物体永远不会被破坏。因此,在创建对象anti时,将调用AntiFloodSys类的构造函数,因此将调用信号与插槽之间的连接。 我的问题是连接超时信号和mySlot在代码的哪一点分开,所以该插槽永远不会触发?

ConsoleInput cpp文件如下所示:

void ConsoleInput::check4Flood(int& lineCounter)
{

    AntiFloodSys anti;

        while(1)
        {
            std::string chatLine[2];
            std::cin >> chatLine[0] >> chatLine[1];
            anti.input(chatLine[0], chatLine[1]);
        }
}

和AntiFloodSys类如下:

AntiFloodSys::AntiFloodSys(QObject *parent) : QObject(parent)



      {
            timeFrame = 1000 ;
            timer = new QTimer;

            connect(timer, SIGNAL(timeout()), this,  SLOT(mySlot()));

            timer->start(timeFrame);
            std::cout << "AntiFloodSys constructor - timer starts "  << "\n";
        }


        AntiFloodSys::~AntiFloodSys()
        {
            std::cout << "AntiFloodSys Destructor" << "\n";
        }

        void AntiFloodSys::input(std::string nick_, std::string line_)
        {
            nick = nick_;
            line = line_;

            std::cout << "nick: " << nick << " line: " << line << " " << "\n";
        }


        void AntiFloodSys::mySlot()
        {
            std::cout << "slot" << "\n";
        }

1 个答案:

答案 0 :(得分:3)

问题出在您的while(1)上:从未处理过Qt事件循环,因为您的程序在该循环中被阻塞了

您可以强制事件循环处理来调用QCoreApplication::processEvents(),但是std::cin是一个阻止函数。因此,它不会完全解决您的问题。

您应该在专用线程中移动循环,该线程会将数据发送到主线程(例如信号/插槽系统)。

您还可以使用QSocketNotifier类创建非阻塞的stdin访问。

一个简单的例子:

class Widget: public QWidget
{
    Q_OBJECT
public:
    Widget(): QWidget(), input(new QLabel("Edit", this))
    {
        connect(this, &Widget::displayText, input, &QLabel::setText);
    }
private:
    QLabel* input;
signals:
    void displayText(QString const&);
};


class UserInput: public QObject
{
    Q_OBJECT
public:
    UserInput(): QObject()
    {}

public slots:
    void run()
    {
        while(1) // User Input in an infinite loop
        {
            std::string line;
            std::cin >> line;
            emit inputReceived(QString::fromStdString(line));
        }
    }
signals:
    void inputReceived(QString const&);
};

int main(int argc, char** argv) {
    QApplication app(argc, argv);
    Widget* w = new Widget();
    UserInput* input = new UserInput();

    QThread* thread = new QThread();
    input->moveToThread(thread); // Move the user input in another thread

    QObject::connect(thread, &QThread::started, input, &UserInput::run);
    QObject::connect(input, &UserInput::inputReceived, w, &Widget::displayText);

    thread->start();
    w->show();

    return app.exec();
}