QQ登录

只需一步,快速开始

 找回密码
 注册

QQ登录

只需一步,快速开始

查看: 1543|回复: 12

色兄,问您一个QT编程问题

[复制链接]
发表于 2006-5-30 01:06:02 | 显示全部楼层 |阅读模式
最近决定为华为客户端写个界面,写得差不多了。但有个问题:

我从QObject和QThread派生出来一个类处理网络操作。

当连接时new一个对象出来,在断开连接时delete掉他。

但是现在每当delete时程序就会崩溃。

看了些文档,也用了deleteLater()。但当其真正消除对象的时候,仍然会崩溃。

该类声明如下:
[code:1]
        class HuaweiNetwork:public QObject, public QThread
        {
       
        Q_OBJECT
                u_char  m_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();

        };
[/code:1]

不知您是否也在写这个界面。如果您写了,我就不写了。不过还请您帮忙解决上面的问题。

多谢!
发表于 2006-5-30 01:34:55 | 显示全部楼层
色兄还没来, 我先随便说几句  

在qt 3中, 跨线程, 不能互相收发signal。 用 QApplication::postEvent
sub class  QCustomEvent 类,自己定义一个event。


另外, 确保线程已经停止运行后, 删除这个对象,如果导致崩溃, 基本都是有所谓的“野指针”引起的。 还有, 在Qt 编程中, 但凡继承 QObject 来的类, 在程序退出时, qt 会自动删除这个对象, 不会造成内存泄漏。 所以, 既然你sub class 了 Qbject, 你也可以让 qt 自己来删。


发言完毕。
回复

使用道具 举报

发表于 2006-5-30 08:48:30 | 显示全部楼层
呵呵,我的QT还只是初学,yunfan要比我强多了,所以我不发言了(其实是不会)
回复

使用道具 举报

 楼主| 发表于 2006-5-30 10:10:05 | 显示全部楼层
[quote:64332bb4d5="yunfan"]色兄还没来, 我先随便说几句  

在qt 3中, 跨线程, 不能互相收发signal。 用 QApplication::postEvent
sub class  QCustomEvent 类,自己定义一个event。


另外, 确保线程已经停止运行后, 删除这个对象,如果导致崩溃, 基本都是有所谓的“野指针”引起的。 还有, 在Qt 编程中, 但凡继承 QObject 来的类, 在程序退出时, qt 会自动删除这个对象, 不会造成内存泄漏。 所以, 既然你sub class 了 Qbject, 你也可以让 qt 自己来删。


发言完毕。 [/quote]

谢谢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的一些基本机制还不太熟。
回复

使用道具 举报

 楼主| 发表于 2006-5-30 10:12:02 | 显示全部楼层
[quote:d89f548e18="sejishikong"]呵呵,我的QT还只是初学,yunfan要比我强多了,所以我不发言了(其实是不会) [/quote]

色兄谦虚了。

sopcast 的界面就是您写的吧?
回复

使用道具 举报

发表于 2006-5-30 11:57:27 | 显示全部楼层


体会一下这句:
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, 色兄谦虚了  
回复

使用道具 举报

发表于 2006-5-30 12:08:38 | 显示全部楼层
我的这个对象并构造时并无指定parent,此时也会被QT自动删除么?


你可以给它一个parent   , 没有parent的, qt 删不了。
不过你上面说的 delete 时 crash, 你还是再检查一下 你的实现文件, 应该有点问题。尤其是有关那几个指针变量, 还有析构函数的处理什么。
回复

使用道具 举报

 楼主| 发表于 2006-5-30 17:42:15 | 显示全部楼层
今天查了一下午,终于查出来了……………………

原来是头文件顺序问题。bug是没了,但仍然有问题:

global.h中声明:
[code:1]

//防止为了字节对齐而在结构体中插入0
#pragma pack(push) // 将当前pack设置压栈保存
#pragma pack(1)// 必须在结构体定义之前使用
//一些结构声明
#pragma pack(pop) // 恢复先前的pack设置

[/code:1]


包含时若将其放在最前,:
[code:1]
#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
        …………
};
}
[/code:1]

则会崩溃,但若将global.h放到最后,则不会崩溃。
#pragma pack(pop)  之后的 pack设置应该已经恢复默认了吧?

为什么会对下面的代码产生影响呢?
回复

使用道具 举报

 楼主| 发表于 2006-5-30 17:47:58 | 显示全部楼层
谢谢yunfan。呵呵,您真是太客气了。以后要多多向您学习。
回复

使用道具 举报

发表于 2006-5-30 21:23:51 | 显示全部楼层
好像很复杂的样子。要用到多重继承。

还是Qt本身设计就是这样的。
回复

使用道具 举报

发表于 2006-5-30 21:45:09 | 显示全部楼层
现在做界面我更倾向于使用 XML 之类的语言来描述,比较简单明了。
回复

使用道具 举报

 楼主| 发表于 2006-5-30 23:22:50 | 显示全部楼层
[quote:74aa1be00d="ricetons"]好像很复杂的样子。要用到多重继承。

还是Qt本身设计就是这样的。[/quote]

QT文档中有这样的代码例子。

如果要在线程中向外发消息,这个应当是比较方便的方法。

当然也可以用 friend class 加Thread成员的方式,但是毕竟不如这样方便。
回复

使用道具 举报

 楼主| 发表于 2006-5-30 23:25:55 | 显示全部楼层
[quote:ca11161c01="heyuqi"]现在做界面我更倾向于使用 XML 之类的语言来描述,比较简单明了。[/quote]

这是我第一次写正儿八经的界面程序。呵呵,以前都是控制台或者matlab。

目前觉得QT还不错。

heyuqi兄所说的方式我还不太了解。以后还要向诸位前辈多多学习。
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 注册

本版积分规则

GMT+8, 2024-11-28 14:38 , Processed in 0.047744 second(s), 16 queries .

© 2021 Powered by Discuz! X3.5.

快速回复 返回顶部 返回列表