如果我有一个A类,它的一个功能是:
void A::func()
{
emit first_signal();
emit second_signal();
}
Run Code Online (Sandbox Code Playgroud)
假设B类有2个插槽,一个连接到first_signal
,和另一对second_signal
中,它保证该连接的时隙first_signal
总是被处理之前的second_signal
时隙?
假设我有一个MyWidget
包含一个MySubWidget
,例如包含文本字段或其他东西的自定义小部件.我希望其他类能够连接到包含的MySubWidget
实例公开的信号和插槽.传统的方法是这样做:
MySubWidget
通过subWidget()
in中的方法公开指向实例的指针MyWidget
MySubWidget
中的MyWidget
类,并用"转发"的代码选择1似乎是最少的代码,但它也有点破坏封装,因为现在其他类知道包含的小部件MyWidget
是什么并且可能依赖于它们的功能.
选择2似乎保持封装,但它有很多看似冗余且可能错综复杂的代码,这会扰乱整个信号和插槽系统的优雅.
在这种情况下通常做什么?
以下链接示例:http://developer.kde.org/documentation/books/kde-2.0-development/ch03lev1sec3.html
#include <QObject>
#include <QPushButton>
#include <iostream>
using namespace std;
class MyWindow : public QWidget
{
Q_OBJECT // Enable slots and signals
public:
MyWindow();
private slots:
void slotButton1();
void slotButton2();
void slotButtons();
private:
QPushButton *button1;
QPushButton *button2;
};
MyWindow :: MyWindow() : QWidget()
{
// Create button1 and connect button1->clicked() to this->slotButton1()
button1 = new QPushButton("Button1", this);
button1->setGeometry(10,10,100,40);
button1->show();
connect(button1, SIGNAL(clicked()), this, SLOT(slotButton1()));
// Create button2 and connect button2->clicked() to this->slotButton2()
button2 = new QPushButton("Button2", this);
button2->setGeometry(110,10,100,40); …
Run Code Online (Sandbox Code Playgroud) 我用一个信号连接一个插槽.但现在我想暂时断开它们.
这是我的班级声明的一部分:
class frmMain : public QWidget
{
...
private:
QTimer *myReadTimer;
...
private slots:
void on_btnDownload_clicked();
...
};
Run Code Online (Sandbox Code Playgroud)
在构造函数中frmMain
,我连接myReadTimer
一个插槽,以便ReadMyCom
每5秒调用一次:
myReadTimer=new QTimer(this);
myReadTimer->setInterval(5000);
connect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
Run Code Online (Sandbox Code Playgroud)
但是,在插槽中on_btnDownload_clicked
.我不想myReadTimer
在on_btnDownload_clicked
范围内发出任何信号.所以我想在开始时断开它们on_btnDownload_clicked
并最终重新连接它们.像这样:
void frmMain::on_btnDownload_clicked()
{
//some method to disconnect the slot & singal
...//the code that I want myReadTimer to leave me alone
//some method to reconnect the slot & singal
}
Run Code Online (Sandbox Code Playgroud)
我在Stackoverflow中搜索并获得了一些答案,比如调用QObject
析构函数.但我不知道如何使用它.
我也试过用disconnect
,比如:
QMetaObject::Connection myConnect;
myConnect=connect(myReadTimer,SIGNAL(timeout()),this,SLOT(ReadMyCom()));
...
disconnect(& …
Run Code Online (Sandbox Code Playgroud) 我有一个Qt应用程序与这种main()...
int main(int argc, char *argv[])
{
QApplication app(argc, argv);
MainWindow mainWin;
... A separate, non-GUI thread is launched here
mainWin.Init();
mainWin.show();
app.exec();
}
Run Code Online (Sandbox Code Playgroud)
在mainWin需要知道何时可以开始与mainWin通信之前创建的另一个线程.但由于mainWin使用Qt信号,插槽,定时器等,因此在事件循环运行之前(通过exec()),它还没有真正准备好.
我的问题是:当事件循环开始时是否会发出一些信号或事件?
考虑一下.在mainWin.Init()中,您可以创建类似QTimer的内容,甚至可以调用.start()来启动它.但实际上它不会被运行并在调用exec()之前触发事件.这就是我需要知道事件循环何时真正开始的原因.
根据条件,我想将按钮连接/重新连接到不同的功能.
假设我有一个按钮:
myButton = QtGui.QPushButton()
Run Code Online (Sandbox Code Playgroud)
对于这个例子,假设我检查是否有互联网连接.
if connected == True:
myButton.clicked.connect(function_A)
elif connected == False:
myButton.clicked.connect(function_B)
Run Code Online (Sandbox Code Playgroud)
首先,我想在重新分配/重新连接到另一个功能(function_A或function_B)之前断开按钮与已连接的任何功能的连接.其次,我已经注意到重新连接按钮后,需要额外点击按钮才能获得新功能.按钮重新连接到另一个功能后,它仍然会尝试运行上一个功能 - 一个按钮之前连接的功能(重新连接之前).请指教.提前致谢!
看起来小部件的.disconnect()方法可用于断开按钮与其连接的功能的连接.
myButton.disconnect()
Run Code Online (Sandbox Code Playgroud)
不幸的是.如果小部件没有连接到任何功能,.disconnect()会抛出错误.为了解决这个问题,我使用了Try/Except.但我宁愿使用更优雅的解决方案......
try: myButton.clicked.disconnect()
except Exception: pass
Run Code Online (Sandbox Code Playgroud) 在这里,我的信号声明:
signals:
void mySignal(MyClass *);
Run Code Online (Sandbox Code Playgroud)
以及我如何使用它:
MyClass *myObject=new myClass();
emit mySignal(myObject);
Run Code Online (Sandbox Code Playgroud)
这是我的问题:谁负责删除myObject:
发件人代码,如果在使用myObject之前删除了什么?悬挂指针
插槽连接到信号,如果没有插槽或连接到信号的多个插槽怎么办?内存泄漏或悬空指针
Qt如何在其内置信号中管理这种情况?它是否使用内部引用计数?
你最好的做法是什么?
对不起,这个问题的幽默措辞.我无法抗拒;-)
如果我emit
的信号没有连接到代码中任何位置的插槽,那么仍然存在与该"发射"相关的性能成本.我不熟悉Qt信号/插槽的实现机制,所以如果这个问题揭示了我对Qt底层设计的基本无知,我深表歉意.
为窗口小部件的信号添加插槽很简单:右键单击它并选择"转到插槽".但是如何on_pushButton_clicked
从Qt设计器中删除为按钮(如)创建的插槽.
我有一个类服务器,我已经创建了一个加入的信号(QString名称).我在一个名为join(QString name)的函数中调用它,但是我收到了错误
Server.o:在函数
Server::join(QString)': Server.cpp:(.text+0x48): undefined reference to
Server :: joined(QString)'collect2:ld返回1退出状态
这是我的头文件的样子:
#ifndef SERVER_H
#define SERVER_H
#include <QString>
#include <mqueue.h>
#include <QVector>
#include <QStringList>
#include "../src/messages.h"
class Server
{
public:
Server();
void start();
private:
void join(QString name);
char buf[MSG_SIZE], msgSend[MSG_SIZE];
QVector<mqd_t> mq_external;
QVector<QString> users;
mqd_t mq_central;
struct mq_attr attr;
signals:
void joined(QString name);
};
#endif // SERVER_H
Run Code Online (Sandbox Code Playgroud)
这是我的cpp文件:
#include "Server.h"
using namespace std;
Server::Server()
{
}
void Server::start(){
attr.mq_maxmsg = 100;
attr.mq_msgsize = MSG_SIZE;
attr.mq_flags = 0;
mq_unlink(CENTRALBOX);
mq_central = …
Run Code Online (Sandbox Code Playgroud) signals-slots ×10
qt ×9
c++ ×5
qt-signals ×2
click ×1
disconnect ×1
event-loop ×1
events ×1
performance ×1
pyqt ×1
python ×1
qt-designer ×1
vtable ×1