posts - 319, comments - 22, trackbacks - 0, articles - 11
  C++博客 :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

1. 示例代码
self.originalPixmap = QtGui.QPixmap.grabWindow(QtGui.QApplication.desktop().winId())

2.关于QPixmap类的grabWIndow

QPixmap QPixmap::grabWindow ( WId window, int x = 0, int y = 0, int width = -1, int height = -1 ) [static]

Creates and returns a pixmap constructed by grabbing the contents of the given window restricted by QRect(x, y, width, height).

The arguments (x, y) specify the offset in the window, whereas (width, height) specify the area to be copied. If width is negative, the function copies everything to the right border of the window. If height is negative, the function copies everything to the bottom of the window.

The window system identifier (WId) can be retrieved using the QWidget::winId() function. The rationale for using a window identifier and not a QWidget, is to enable grabbing of windows that are not part of the application, window system frames, and so on.

The grabWindow() function grabs pixels from the screen, not from the window, i.e. if there is another window partially or entirely over the one you grab, you get pixels from the overlying window, too. The mouse cursor is generally not grabbed.

Note on X11 that if the given window doesn't have the same depth as the root window, and another window partially or entirely obscures the one you grab, you will not get pixels from the overlying window. The contents of the obscured areas in the pixmap will be undefined and uninitialized.

On Windows Vista and above grabbing a layered window, which is created by setting the Qt::WA_TranslucentBackground attribute, will not work. Instead grabbing the desktop widget should work.

Warning: In general, grabbing an area outside the screen is not safe. This depends on the underlying window system.

posted @ 2011-04-29 22:56 RTY 阅读(1442) | 评论 (0)编辑 收藏

有的时候,我们希望自己的操作带上系统的响铃。
可以这样操作:
            QtGui.qApp.beep()


以下是beep的说明

void QApplication::beep () [static]

Sounds the bell, using the default volume and sound. The function is not available in Qt for Embedded Linux.

posted @ 2011-04-29 22:53 RTY 阅读(429) | 评论 (0)编辑 收藏

         我们中的大多数人都经历过费解代码的纠缠。我们中的许多人自己就编写过费解的代码。写出自己能理解的代码很容易,因为在写这些代码时,我们正深入于要解决的问题中。代码的其他维护者不会那么深入,也就不易理解代码。
         软件项目的主要成本在于长期维护。为了在修改时尽量降低出现缺陷的可能性,很有必要理解系统是做什么的。当系统变得越来越复杂,开发者就需要越来越多的时间来理解它,而且业绩有可能误解。所以,代码应当清晰地表达其作者的意图。作者把代码写得越清晰,其他人花在理解代码上的时间也就越少,从而减少缺陷,缩减维护成本。
       可以通过选用好名称来表达。我们想要听到好类名和好函数名,而且在查看其权则时不会大吃一惊。
       也可以通过保持函数和类尺寸短小来表达。短小的类和函数通常易于命名,易于编写,易于理解。
       还可以通过采用标准命名法来表达。例如,设计模式很多大程度上就关乎沟通和表达。通过在实现这些模式的类的名称中采用标准模式名,例如COMMAND或VISITOR,就能充分地向其他开发者描述你的设计。
       编写良好的单元测试也具有表达性。测试的主要目的之一就是通过实例起到文档的作用。读到测试的人应该能很快理解某个类是做什么的。
       不过,做到表达力的最重要方式却是尝试。有太多时候,我们写出能工作的代码,就转移到下一个问题上,没有下足功夫调整代码,让后来者易于阅读。技战术,下一位读代码的人最有可能是你自己。
       所以,多少尊重一下你的手艺吧。花一点点时间在每个函数和类上。选用较好的名称,将大函数切分为小函数,时时关注自己创建的东东,用心是最珍贵的资源。

posted @ 2011-04-26 21:20 RTY 阅读(291) | 评论 (0)编辑 收藏

1、使用异常而非返回码
例子:
public class DeviceController {
public void sendShutDown() {
  try {
     tryToShutDown();
  } catch (DeviceShutDownError e) {
     logger.log(e);
}


private void tryToShutDown() throws DeviceShutDownError {
..
}

2. 别返回null值
检查null 值出现的问题

posted @ 2011-04-25 21:46 RTY 阅读(300) | 评论 (0)编辑 收藏

下载地址:http://sourceforge.net/projects/gecrit/files/

posted @ 2011-04-23 18:07 RTY 阅读(440) | 评论 (0)编辑 收藏

     摘要: assert() 函数用法  阅读全文

posted @ 2011-04-20 21:18 RTY 阅读(991) | 评论 (0)编辑 收藏

     摘要: 标准C++的一些约定   阅读全文

posted @ 2011-04-20 21:15 RTY 阅读(139) | 评论 (0)编辑 收藏

     摘要: Windows 60个常用API附录A 常用的Windows API 调用本附录列出了PowerBuilder 常用Windows API 系统调用同时给出了这些函数的功能说明方式以及应用示例下表首先给出常用API 调用的名称和扼要功能读者需要详细了解某个函数的声明格式和示例时可通过序号在本附录中找到相应说明表A 常用的Windows API 系统序号 函数 功能1 Arc() 在窗口上画一条弧线...  阅读全文

posted @ 2011-04-19 23:23 RTY 阅读(1363) | 评论 (0)编辑 收藏

写的不错,转一下:

首先呢,声明一下,QString 是不存在中文支持问题的,很多人遇到问题,并不是本身 QString 的问题,而是没有将自己希望的字符串正确赋给QString。

很简单的问题,"我是中文"这样写的时候,它是传统的 char 类型的窄字符串,我们需要的只不过是通过某种方式告诉QString 这四个汉字采用的那种编码。而问题一般都出在很多用户对自己当前的编码没太多概念,

于是

一个简 单的 Qt 程序

下面这个小程序,估计大家会感到比较亲切。似乎有相当多的中文用户尝试写过这样的代码:

#include <QtGui/QApplication>
#include <QtGui/QLabel>

int main(int argc, char **argv)
{
QApplication app(argc, argv);
QString a= "我是汉字";
QLabel label(a);
label.show();
return app.exec();
}

编码,保存,编译,运行,一切都很顺利,可是结果呢?

多数用户看到

其他用户看到

ÎÒÊǺº×Ö

æˆ‘æ˜¯æ±‰å —

出乎意料,界面上中文没显示出来,出现了不认识字符。 于是开始用搜索引擎搜索,开始上论坛发帖或抱怨

最后被告知,下面的语句之一可以解决问题:

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

两条指令挨个一试,确实可以解决(多数用户是第一条,其他用户是第二条)。那么,为什么会这样呢?

两种乱码什么时候出现

对这个问题,我想大家可能都有话说。在继续之前,我们先列个表,看看两种乱码分别在那种情况下出现:

我们只列举大家最常用的3个编译器(微软VS的中的cl,Mingw中的g++,Linux下的g++),源代码分别采用 GBK 和 不带BOM的UTF-8  以及 带BOM的UTF-8 这3中编码进行保存。

源代码的编码

编译器

结果

GBK

cl

1

*

mingw-g++

1

*

g++

1

UTF-8(不带BOM)

cl

2

mingw-g++

2

g++

2

*

UTF-8(带BOM)

cl

1

mingw-g++

2

g++

编译失败

采用3种不同编码保存的源代码文件,分别用3种不同的编译器编译,形成9种组合,除掉一种不能工作的情况,两种乱码出现的情况各占一半。

从中我们也可以看出,乱码和操作系统原本是没有关系的。但我们在 Windows 一般用的GBK,linux一般用的是不带BOM的UTF-8。如果我们只考虑带*的情况,也可以说两种乱码和系统有关。

QString 为什么会乱码呢?

真的是 QString 乱码了吗?我们可以问问自己,我们抱怨的对象是不是搞错了?

继续之前,先明确几个概念:

明确概念1:

"我是汉字" 是C语言中的字符串,它是char型的窄字符串。上面的例子可写为

const char * str = "我是汉字";
QString a= str;

char str[] = "我是汉字";
QString a= str;

明确概念2:

源文件是有编码的,但是这种纯文本文件却不会记录自己采用的编码

这个是问题的根源,不妨做个试验,将前面的源代码保存成GBK编码,用16进制编辑器能看到引号内是ce d2 ca c7 ba ba d7 d6这样8个字节。

现在将该文件拷贝到正体(繁体)中文的Windows中,用记事本打开会什么样子呢?

...
QString a= "扂岆犖趼";
QLabel label(a);
label.show();
...

那么放到欧美人的Windows系统中,再用记事本打开呢?

...
QString a= "ÎÒÊǺº×Ö";
QLabel label(a);
label.show();
...

同一个文件,未做任何修改,但其中的8个字节ce d2 ca c7 ba ba d7 d6,对用GBK的大陆人,用BIG5的港澳台同胞,以及用Latin-1的欧洲人看来,看到的却是完全不同的文字。

明确概念3:

如同我们都了解的'A'与'\x41'等价一样。

GBK编码下的

const char * str = "我是汉字"

等价于

const char * str = "\xce\xd2\xca\xc7\xba\xba\xd7\xd6";

当用UTF-8编码时,等价于

const char * str = "\xe6\x88\x91\xe6\x98\xaf\xe6\xb1\x89\xe5\xad\x97";

注意:这个说法不全对,比如保存成带BOM的UTF-8,用cl编译器时,汉字本身是UTF-8编码,但程序内保存时却是对应的GBK编码。

明确概念4:

QString 内部采用的是Unicode。

QString内部采用的是 Unicode,它可以同时存放GBK中的字符"我是汉字",BIG5中的字符"扂岆犖趼" 以及Latin-1中的字符"ÎÒÊǺº×Ö"。

一个问题是,源代码中的这8个字节"\xce\xd2\xca\xc7\xba\xba\xd7\xd6",该怎么转换成Unicode并存到 QString 内?按照GBK、BIG5、Latin-1还是其他方式...

在你不告诉它的情况下,它默认选择了Latin-1,于是8个字符"ÎÒÊǺº×Ö"的unicode码被存进了QString中。最终,8个Latin字符出现在你期盼看到4中文字符的地方,所谓的乱码出现了

QString 工作方式

const char * str = "我是汉字";
QString a= str;

其实很简单的一个问题,当你需要从窄字符串 char* 转成Unicode的QString字符串的,你需要告诉QString你的这串char* 中究竟是什么编码?GBK、BIG5、Latin-1

理想情况就是:将char* 传给QString时,同时告诉QString自己的编码是什么:

就像下面的函数一样,QString的成员函数知道按照何种编码来处理 C 字符串

QString QString::fromAscii ( const char * str, int size = -1 )
QString QString::fromLatin1 ( const char * str, int size = -1 )
QString QString::fromLocal8Bit ( const char * str, int size = -1 )
QString QString::fromUtf8 ( const char * str, int size = -1 )

单QString 只提供了这几个成员函数,远远满足不了大家的需求,比如,在简体中文Windows下,local8Bit是GBK,可是有一个char串是 BIG5 或 Latin-2怎么办?

那就动用强大的QTextCodec吧,首先QTextCodec肯定知道自己所负责的编码的,然后你把一个char串送给它,它就能正确将其转成Unicode了。

QString QTextCodec::toUnicode ( const char * chars ) const

可是这个调用太麻烦了,我就想直接

QString a= str;

QString a(str);

这样用怎么办?

这样一来肯定没办法同时告诉 QString 你的str是何种编码了,只能通过其他方式了。这也就是开头提到的

QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GBK"));
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));

设置QString默认采用的编码。而究竟采用哪一个,一般来说就是源代码是GBK,就用GBK,源代码是UTF-8就用UTF-8。但有一个例外,如果你保存成了带BOM的UTF-8而且用的微软的cl编译器,此时仍是GBK。

posted @ 2011-04-19 23:09 RTY 阅读(459) | 评论 (0)编辑 收藏

在使用C++编程的过程中,常常需要对类成员进行初始化,通常的方法有两种:

第一种方法:

CMYClass::CSomeClass()
{
x
=0;
y
=1;
}

第二种方法:

CSomeClass::CSomeClass() : x(0), y(1)
{
}

 

本文将要探讨这两种方法的异同以及如何使用这两种方法。

    从技术上说,第二种方法比较好,但是在大多数情况下,两者实际上没有什么区别。第二种语法被称为成员初始化列表,之所以要使用这种语法有两个原因:一个原因是必须这么做,另一个原因是出于效率考虑。

    让我们先看一下第一个原因——必要性。设想你有一个类成员,它本身是一个类或者结构,而且只有一个带一个参数的构造函数。

 

class CMyClass {
CMember m_member;
public:
CMyClass();
};

 

// 必须使用初始化列表来初始化成员 m_memberCMyClass::CMyClass() : m_member(2){•••}
    没有其它办法将参数传递给m_member,如果成员是一个常量对象或者引用也是一样。根据C++的规则,常量对象和引用不能被赋值,它们只能被初始化。

    使用初始化列表的第二个原因是出于效率考虑,当成员类具有一个缺省的构造函数和一个赋值操作符时。MFC的CString提供了一个完美的例子。假定你有一个类CMyClass具有一个CString类型的成员m_str,你想把它初始化为"Hi,how are you."。你有两种选择:

CMyClass::CMyClass() {// 使用赋值操作符// CString::operator=(LPCTSTR);m_str = _T("Hi,how are you.");}
// 使用初始化列表// 和构造函数 CString::CString(LPCTSTR)CMyClass::CMyClass() : m_str(_T("Hi,how are you.")){}
    在它们之间有什么不同吗?是的。编译器总是确保所有成员对象在构造函数体执行之前被初始化,因此在第一个例子中编译的代码将调用CString::Cstring来初始化m_str,这在控制到达赋值语句前完成。在第二个例子中编译器产生一个对CString:: CString(LPCTSTR)的调用并将"Hi,how are you."传递给这个函数。结果是在第一个例子中调用了两个CString函数(构造函数和赋值操作符),而在第二个例子中只调用了一个函数。

    在CString的例子里这是无所谓的,因为缺省构造函数是内联的,CString只是在需要时为字符串分配内存(即,当你实际赋值时)。但是,一般而言,重复的函数调用是浪费资源的,尤其是当构造函数和赋值操作符分配内存的时候。在一些大的类里面,你可能拥有一个构造函数和一个赋值操作符都要调用同一个负责分配大量内存空间的Init函数。在这种情况下,你必须使用初始化列表,以避免不要的分配两次内存。

    在内建类型如ints或者longs或者其它没有构造函数的类型下,在初始化列表和在构造函数体内赋值这两种方法没有性能上的差别。不管用那一种方法,都只会有一次赋值发生。有些程序员说你应该总是用初始化列表以保持良好习惯,但我从没有发现根据需要在这两种方法之间转换有什么困难。在编程风格上,我倾向于在主体中使用赋值,因为有更多的空间用来格式化和添加注释,你可以写出这样的语句:
x=y=z=0;
或者
memset(this,0,sizeof(this));
注意第二个片断绝对是非面向对象的。

    当我考虑初始化列表的问题时,有一个奇怪的特性我应该警告你,它是关于C++初始化类成员的,它们是按照声明的顺序初始化的,而不是按照出现在初始化列表中的顺序。

class CMyClass {    CMyClass(int x, int y);    int m_x;    int m_y;};CMyClass::CMyClass(int i) : m_y(i), m_x(m_y){}
    你可能以为上面的代码将会首先做m_y=i,然后做m_x=m_y,最后它们有相同的值。但是编译器先初始化m_x,然后是m_y,,因为它们是按这样的顺序声明的。结果是m_x将有一个不可预测的值。这个例子是故意这样设计来说明这一点的,然而这种bug会很自然地出现。有两种方法避免它,一个是总是按照你希望它们被初始化的顺序来声明成员,第二个是,如果你决定使用初始化列表,总是按照它们声明的顺序罗列这些成员。这将有助于消除混淆。

class CMember {
public:
CMember(
int x) { ... }
};

因为CMember有一个显式声明的构造函数,编译器不产生一个缺省构造函数(不带参数),所以没有一个整数就无法创建CMember的一个实例。

CMember* pm = new CMember;        // 出错!!
CMember* pm = new CMember(2);     // OK

    如果CMember是另一个类的成员,你怎样初始化它呢?答案是你必须使用成员初始化列表。

posted @ 2011-04-19 23:04 RTY 阅读(222) | 评论 (0)编辑 收藏

仅列出标题
共31页: First 23 24 25 26 27 28 29 30 31