色兄,问您一个QT编程问题
最近决定为华为客户端写个界面,写得差不多了。但有个问题:我从QObject和QThread派生出来一个类处理网络操作。
当连接时new一个对象出来,在断开连接时delete掉他。
但是现在每当delete时程序就会崩溃。
看了些文档,也用了deleteLater()。但当其真正消除对象的时候,仍然会崩溃。
该类声明如下:
class HuaweiNetwork:public QObject, public QThread
{
Q_OBJECT
u_charm_DestMac[6]; //目标MAC
pcap_t *m_fp; //网卡设备
USERDATA m_Data;//用户数据
bool isonline;
signals:
void Message(const char *);
void Connected();
void ConnectionInterrupted();
protected:
bool SendVersion(const u_char Id);
bool SendUsername(const u_char Id);
bool SendPassword(const u_char Id, const u_char *Chap);
bool SendKeeponline(const u_char Id);
bool OpenAdapter();
void CloseAdapter();
void SetMd5Buf(PPASSWORDFRM pBuf, const u_char ID, const u_char *chap);
void InitBuf(u_char *buf);
bool SendLogin();
bool SendLogout();
virtual void run();
public:
HuaweiNetwork(const QString & username, const QString & passwd, const QString & interfacenum, int * ip, int *mac);
void Connect();
void DisConnect();
};
不知您是否也在写这个界面。如果您写了,我就不写了。不过还请您帮忙解决上面的问题。
多谢! 色兄还没来, 我先随便说几句:lol:
在qt 3中, 跨线程, 不能互相收发signal。 用 QApplication::postEvent
sub classQCustomEvent 类,自己定义一个event。
另外, 确保线程已经停止运行后, 删除这个对象,如果导致崩溃, 基本都是有所谓的“野指针”引起的。 还有, 在Qt 编程中, 但凡继承 QObject 来的类, 在程序退出时, qt 会自动删除这个对象, 不会造成内存泄漏。 所以, 既然你sub class 了 Qbject, 你也可以让 qt 自己来删。
发言完毕。 :-D 呵呵,我的QT还只是初学,yunfan要比我强多了,所以我不发言了(其实是不会) :mrgreen: 色兄还没来, 我先随便说几句:lol:
在qt 3中, 跨线程, 不能互相收发signal。 用 QApplication::postEvent
sub classQCustomEvent 类,自己定义一个event。
另外, 确保线程已经停止运行后, 删除这个对象,如果导致崩溃, 基本都是有所谓的“野指针”引起的。 还有, 在Qt 编程中, 但凡继承 QObject 来的类, 在程序退出时, qt 会自动删除这个对象, 不会造成内存泄漏。 所以, 既然你sub class 了 Qbject, 你也可以让 qt 自己来删。
发言完毕。 :-D
谢谢yunfan!
不过我的代码从线程中向界面发signal,界面是可以收到的。我查看的是Qt assistant:
The Signals and Slots mechanism can be used in separate threads, as long as the rules for QObject based classes are followed. The Signals and Slots mechanism is synchronous: when a signal is emitted, all slots are called immediately. The slots are executed in the thread context that emitted the signal.
Warning: Slots that generate window system events or use window system functions must not be connected to a signal that is emitted from a thread that is not the GUI thread. See the Qt Library Mutex section above for more details.
我的这个对象并构造时并无指定parent,此时也会被QT自动删除么?
另外,我的代码要求在断开连接的时候就释放对象,以便再次连接的时候重新new一个出来。所以让QT自动删除似乎不可行。
我没有重新实现析构函数。但是delete的时候就会出错。此时确定线程已经终止,网卡已关闭。
请yunfan帮忙解决一下吧。我对QT的一些基本机制还不太熟。 呵呵,我的QT还只是初学,yunfan要比我强多了,所以我不发言了(其实是不会) :mrgreen:
色兄谦虚了。
sopcast 的界面就是您写的吧? :mrgreen:
体会一下这句:
Warning: Slots that generate window system events or use window system functions must not be connected to a signal that is emitted from a thread that is not the GUI thread.
你这个 thread 不是 qwidget 的继承类, 是个 非 GUI thread。 如果你要在gui 线程里修改一些有关界面的东西, 会有问题。Qt 程序中, 有关gui更新部分是独立的线程,其实就是你程序main进来以后的那个线程, QApplication 会开一个线程用来处理event, 它会通知gui线程(主线程来更新显示等等)。 我上面说的不合适, 先道歉。 因为跨线程, 我都不用signal这种机制(Qt 4 是后话了), 所以我说的有点经验主意了。 不好意思。
稀里糊涂的说了一堆, 就一个意思, qt 3 里不推荐跨线程的connect 信号和槽。 因为一点牵扯到界面更改, 就无效了。(我没记错的话, 是更新界面部分会失效)。
顺便怕一下色兄MP, 色兄谦虚了:mrgreen: 我的这个对象并构造时并无指定parent,此时也会被QT自动删除么?
你可以给它一个parent:-D , 没有parent的, qt 删不了。
不过你上面说的 delete 时 crash, 你还是再检查一下 你的实现文件, 应该有点问题。尤其是有关那几个指针变量, 还有析构函数的处理什么。 今天查了一下午,终于查出来了……………………
原来是头文件顺序问题。bug是没了,但仍然有问题:
global.h中声明:
//防止为了字节对齐而在结构体中插入0
#pragma pack(push) // 将当前pack设置压栈保存
#pragma pack(1)// 必须在结构体定义之前使用
//一些结构声明
#pragma pack(pop) // 恢复先前的pack设置
包含时若将其放在最前,:
#include "global.h"
#include "pcap.h"
#include <qobject.h>
#include <qstring.h>
#include <qthread.h>
namespace NetworkOperation{
class HuaweiNetwork:public QObject, public QThread
{
Q_OBJECT
…………
};
}
则会崩溃,但若将global.h放到最后,则不会崩溃。
#pragma pack(pop)之后的 pack设置应该已经恢复默认了吧?
为什么会对下面的代码产生影响呢? 谢谢yunfan。呵呵,您真是太客气了。以后要多多向您学习。 好像很复杂的样子。要用到多重继承。
还是Qt本身设计就是这样的。 现在做界面我更倾向于使用 XML 之类的语言来描述,比较简单明了。 好像很复杂的样子。要用到多重继承。
还是Qt本身设计就是这样的。
QT文档中有这样的代码例子。
如果要在线程中向外发消息,这个应当是比较方便的方法。
当然也可以用 friend class 加Thread成员的方式,但是毕竟不如这样方便。 现在做界面我更倾向于使用 XML 之类的语言来描述,比较简单明了。
这是我第一次写正儿八经的界面程序。呵呵,以前都是控制台或者matlab。
目前觉得QT还不错。
heyuqi兄所说的方式我还不太了解。以后还要向诸位前辈多多学习。
页:
[1]