【问题标题】:Qt slot is not activatedQt 插槽未激活
【发布时间】:2019-07-29 22:58:28
【问题描述】:

所以我有 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";
        }

【问题讨论】:

    标签: c++ qt


    【解决方案1】:

    问题是你的while(1):Qt 事件循环永远不会被处理,因为你的程序在这个循环中被阻塞

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

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

    您还可以使用 QSocketNotifier 类来创建非阻塞标准输入访问。

    一个简单的例子:

    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();
    }
    

    【讨论】:

    • 在 unixy 系统上,您还可以使用 QSocketNotifierstdin 获取数据,但这在 Windows 上不起作用(因为控制台不是“文件”就像在类 Unix 系统上一样)。
    猜你喜欢
    • 2020-01-30
    • 1970-01-01
    • 1970-01-01
    • 2023-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-11
    • 2015-03-14
    • 1970-01-01
    相关资源
    最近更新 更多