所以我有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";
}
答案 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();
}