有一个类QNetworkReply的对象.有一个插槽(在某些其他对象中)连接到其finished()信号.信号是同步的(默认值).只有一个主题.
在某些时刻,我想摆脱两个对象.没有更多的信号或任何东西.我希望他们走了.好吧,我想,我会用的
delete obj1; delete obj2;
Run Code Online (Sandbox Code Playgroud)
但我真的可以吗?~QObject的规格说:
等待传递挂起事件时删除QObject可能会导致崩溃.
什么是"待定事件"?这是否意味着当我打电话给我时delete,已经有一些"未决事件"要发送,并且它们可能会导致崩溃,我无法确定是否有任何?
所以我要说我打电话:
obj1->deleteLater(); obj2->deleteLater();
Run Code Online (Sandbox Code Playgroud)
为了安全起见.
但是,我真的很安全吗?该deleteLater补充说,将在主回路控制时到达那里进行处理的事件.是否有一些待处理事件(信号)obj1或obj2已经存在,等待在处理deleteLater 之前在主循环中处理?那将是非常不幸的.我不想编写"有点删除"状态的代码检查,并忽略所有插槽中的传入信号.
Qt文档指出信号和槽可以是direct,queued和auto.
它还声明,如果拥有插槽的对象'生命'在与拥有信号的对象不同的线程中,则发出此类信号就像发布消息一样 - 信号发出将立即返回,并且将在目标线程的事件循环中调用slot方法.
不幸的是,文档没有说明"生命"代表的是没有例子可用.我试过以下代码:
main.h:
class CThread1 : public QThread
{
Q_OBJECT
public:
void run( void )
{
msleep( 200 );
std::cout << "thread 1 started" << std::endl;
MySignal();
exec();
}
signals:
void MySignal( void );
};
class CThread2 : public QThread
{
Q_OBJECT
public:
void run( void )
{
std::cout << "thread 2 started" << std::endl;
exec();
}
public slots:
void MySlot( void )
{
std::cout << "slot called" << std::endl;
} …Run Code Online (Sandbox Code Playgroud) 当其中一个边被删除时,Qt会自动删除对象之间的连接吗?
例如connect (A .. , B ..),当删除A(指针)或删除B时,是否会断开连接?
是否有必要在析构函数中明确使用disconnect?
我在使用Qt信号时遇到问题.
我不明白怎么做DirectConnection和QueuedConnection有效?
如果有人会解释何时使用其中的哪一个(示例代码将被赞赏),我将感激不尽.
Qt信号可以是公共的还是私人的?我可以创建只在课堂内看到的内部信号吗?
更新:我有一个带有一些内部信号的课程.如何让这些信号对其他类不可见(封装和信息隐藏)?
当实现类已经从QObject/QWidget中获取时,如何在抽象类/接口中声明Qt信号?
class IEmitSomething
{
public:
// this should be the signal known to others
virtual void someThingHappened() = 0;
}
class ImplementEmitterOfSomething : public QWidget, public IEmitSomething
{
// signal implementation should be generated here
signals: void someThingHappended();
}
Run Code Online (Sandbox Code Playgroud) 我们正在使用提供信号和插槽的Qt,我觉得非常方便.然而,强大的力量带来了巨大的责任,我认为很容易滥用这个功能.
是否有信号槽使用的最佳实践?我很难以这种方式找到一些通用指南.一些问题(我有明确的意见,但并非所有团队成员都同意):
signal displayInfoScreen()必须由显示信息屏幕的插槽处理.关于何时应该/不应该使用信号的任何其他意见都是非常受欢迎的!
SO上的尊重答案与实际的Qt文档之间存在差异.
我已经阅读了这个问题,我想进一步澄清一下.有人可以证实:
protected,因此它只能由类或其任何子类发出.我不确定这是真的; 上面的问题显示了支持这一陈述的答案.但Qt文档说:Signals are public access functions and can be emitted from anywhere, but we recommend to only emit them from the class that defines the signal and its subclasses.那是什么?a signal emitted from an instance of an arbitrary class can cause a private slot to be invoked in an instance of an unrelated class.这意味着private信号/插槽机制不尊重它?signal关键字时,public,private,protected这两个词没有用处connect函数将类名称作为信号前缀(即SomeClass::itsSignal …我检查了其他类似的问题,并尝试了他们的解决方案,但他们不适合我.
我基本上试图创建一个只发出帖子请求的http客户端.为了做到这一点,我需要将QNetworkManager完成的信号连接到一些回调插槽.
这是我的代码.
h文件:
...
public slots:
void finishedSlot(QNetworkReply* reply);
private:
QNetworkAccessManager *network_manager;
...
Run Code Online (Sandbox Code Playgroud)
cpp文件:
...
Class1::Class1(){
network_manager = new QNetworkAccessManager(this);
QObject::connect(network_manager, SIGNAL(finished(QNetworkReply *)), this, SLOT(finishedSlot(QNetworkReply *)));
}
...
void Class1::finishedSlot(QNetworkReply* reply)
{
// some logic with reply
}
...
Run Code Online (Sandbox Code Playgroud)
如您所见,插槽肯定存在,并在头文件的公共插槽下声明.所以我不知道为什么会这样.我已经尝试过干净,运行qmake,然后重建.
错误消息是:
"QObject :: connect:没有这样的插槽QObject :: finishedSlot(QNetworkReply*)"
任何的想法?
读了一些文章后,像这样关于Qt信号插槽通信还是有关于排队的连接问题.
如果我有一些线程一直向对方发送信号,并且假设一个thread_slow在它的事件循环中运行一个慢速方法而另一个thread_fast运行一个快速的方法发送多个信号,而另一个线程仍在运行它的慢速方法...... ..当thread_slow返回到事件循环的慢速方法时,它会处理之前发送的所有信号thread_fast还是最后一个发送的所有信号(所有信号都是相同的类型)?
如果它将处理所有信号,是否有办法使thread_slow 唯一的过程成为最后一个?(考虑到多线程应用程序中的"最后一个"可能是模糊的,让我们考虑线程要求最后一个信号之前的最后一个信号,为了简单起见,所以在线程查找最后一个时发送的新信号可能会丢失).
(我问这个是因为我有多个线程从多个线程接收数据,我不希望它们处理旧数据,只是最后一个发送的数据)
我已经进行了一些测试,看来Qt将处理所有信号.我做了一个线程:
while(true)
{
QThread::msleep(500);
emit testQueue(test);
test++;
}
Run Code Online (Sandbox Code Playgroud)
另一个插槽将执行:
void test::testQueue(int test)
{
test.store(private_test.load() + test);
emit testText(QString("Test Queue: ") + QString::number(private_test.load()));
}
Run Code Online (Sandbox Code Playgroud)
并且线程将运行:
while(true)
{
QThread::msleep(3000);
QCoreApplication::processEvents();
private_test.store(private_test.load() + 1000);
}
Run Code Online (Sandbox Code Playgroud)
我每隔500毫秒从一个线程向另一个线程发送一个信号,另一个线程休眠3000毫秒(3秒)然后唤醒并将内部变量递增100.每次执行一个插槽时它会发出一个文本收到的值+内部变量.我得到的结果是,每次 QCoreApplication::processEvents();调用,所有信号都被执行....(我编辑了这部分是因为我在之前的代码中发现了一个错误)