#import <QuartzCore/QuartzCore.h> @implementation UIView (NKShadow) // add the shadow effect to the view -(void)addShadow{ self.layer.shadowOpacity = 0.4; self.layer.shadowRadius = 0.9; self.layer.shadowOffset = CGSizeMake(0, 0); UIBezierPath *path = [UIBezierPath bezierPath]; CGPoint p1 = CGPointMake(self.frame.origin.x, self.frame.origin.y+self.frame.size.height); CGPoint p2 = CGPointMake(self.frame.origin.x+self.frame.size.width, p1.y); CGPoint c1 = CGPointMake((p1.x+p2.x)/4 , p1.y+6.0); CGPoint c2 = CGPointMake(c1.x*3, c1.y); [path moveToPoint:p1]; [path addCurveToPoint:p2 controlPoint1:c1 controlPoint2:c2]; self.layer.shadowPath = path.CGPath; } -(void)addGrayGradientShadow{ // 0.8 is a good feeling shadowOpacity self.layer.shadowOpacity = 0.4; // The Width and the Height of the shadow rect CGFloat rectWidth = 10.0; CGFloat rectHeight = self.frame.size.height; // Creat the path of the shadow CGMutablePathRef shadowPath = CGPathCreateMutable(); // Move to the (0, 0) point CGPathMoveToPoint(shadowPath, NULL, 0.0, 0.0); // Add the Left and right rect CGPathAddRect(shadowPath, NULL, CGRectMake(0.0-rectWidth, 0.0, rectWidth, rectHeight)); CGPathAddRect(shadowPath, NULL, CGRectMake(self.frame.size.width, 0.0, rectWidth, rectHeight)); self.layer.shadowPath = shadowPath; CGPathRelease(shadowPath); // Since the default color of the shadow is black, we do not need to set it now //self.layer.shadowColor = [UIColor blackColor].CGColor; self.layer.shadowOffset = CGSizeMake(0, 0); // This is very important, the shadowRadius decides the feel of the shadow self.layer.shadowRadius = 10.0; } @end
shadow是有path的, 你可以自己画那个path,来做你想要的效果。
void* realloc(void* ptr, unsigned newsize);
void* malloc(unsigned size);
void* calloc(size_t numElements, size_t sizeOfElement);
都在stdlib.h函数库内
它们的返回值都是请求系统分配的地址,如果请求失败就返回NULL
malloc用于申请一段新的地址,参数size为需要内存空间的长度,如:
char* p;
p=(char*)malloc(20);
calloc与malloc相似,参数sizeOfElement为申请地址的单位元素长度,numElements为元素个数,如:
char* p;
p=(char*)calloc(20,sizeof(char));
这个例子与上一个效果相同
realloc是给一个已经分配了地址的指针重新分配空间,参数ptr为原有的空间地址,newsize是重新申请的地址长度
如:
char* p;
p=(char*)malloc(sizeof(char)*20);
p=(char*)realloc(p,sizeof(char)*40);
注意,这里的空间长度都是以字节为单位。
这里重点说下realloc:
realloc 用过很多次了。无非就是将已经存在的一块内存扩大。
char* p = malloc(1024);
char* q = realloc(p,2048);
现在的问题是我们应该如何处理指针 p。 刚开始按照我最直观的理解,如果就是直接将 p = NULL;。 到最后只需要释放 q的空间就可以了。
因为最近在做个封装。结果在做单元测试的时候发现。有时候我在 free(q); 的时候会出错。这样我就郁闷了。
后来仔细一跟踪,发现 realloc 完以后 q 和 p 的指针地址是一样。不过有时候又不一样。
仔细查了下资料。得到如下信息:
1.如果 当前连续内存块足够 realloc 的话,只是将p所指向的空间扩大,并返回p的指针地址。 这个时候 q 和 p 指向的地址是一样的。
2.如果 当前连续内存块不够长度,再找一个足够长的地方,分配一块新的内存,q,并将 p指向的内容 copy到 q,返回 q。并将p所指向的内存空间删除。
这样也就是说 realloc 有时候会产生一个新的内存地址 有的时候不会。所以在分配完成后。我们需要判断下 p 是否等于 q。并做相应的处理。
这里有点要注意的是要避免 p = realloc(p,2048); 这种写法。有可能会造成 realloc 分配失败后,p原先所指向的内存地址丢失。
我的话:其实在这里我们不需要处理p(指无需释放内存),为什么呢?
按照msdn上的说法,函数在调用的时候会出现三种情况,接下来我重点说这三种情况:
1. 成功在其后增加指定的空间,这种情况是不需要处理p的,因为p==q
2. 指定其后分配的空间不足,从而从新分配和赋值.q的内存其实已经帮我们释放了.我们更没有理由去管它.
3. 系统分配失败,将保持原来的大小不变.这是我们只要判断p是否为空即可.
SYSZUXpinyin输入法完全是用qt搭建的,移植到arm平台后,可以弹出软键盘,本人已成功。移植过程可以参考http://blog.chinaunix.net/uid-24219701-id-3077611.html这里,等有时间洒家写个移植的小细节。这里主要讲,移植后整个程序的文本、字符编码方式怎么调整才能避免乱码。
我的环境是在Fedora14下,默认的编码方式是UTF-8,在未移植SYSZUX拼音之前,main函数里设置:
QTextCodec::setCodecForTr(QTextCodec::codecForName("UTF-8")); //UTF-8
QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
如此设置,UDP的接收端和发送端都可以正常显示中文。但SYSZUXpinyin采用的是GB2312方式,在主函数里必须设置 QTextCodec::setCodecForTr(QTextCodec::codecForName("GB2312")); 在弹出的软键盘里才能正常显示中文。值得交代的是,main函数里只需要加这一句就可以了,多加任何如QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));或者QTextCodec::setCodecForCStrings(QTextCodec::codecForName("GB2312"))都会让软键盘显示异常!这块也是最纠结的地方.
主函数里设成GB2312后,除了按钮上的汉字可以正常显示外,其他的如标题等都不能正常显示了。因为我们的linux下qt默认的中文环境是UTF-8格式,要正常显示中文必须转化成UTF-8格式。解决方法是:在widget.h里,#include <QTextCodec>,然后定义: QTextCodec *tc; 在widget.cpp的构造函数里:tc = QTextCodec::codecForName("UTF-8"); 以后显示中文就用如: this->setWindowTitle(tc->toUnicode("Esto网络通讯模块----客户端"))来显示!
奇怪的是本地EditText是可以正常显示的,如ui->getTextEdit->insertPlainText( sendStr +"\n");操蛋就操蛋在发送端和接收端。在对端上中文都是乱码。我原以为tr设成GB2312后,对CStrings默认的也成了GB2312.既然发送端是GB2312,我曾实验发送端GB2312-----------接收端GB2312解析,显示出来还是乱码。将解析的GB2312再转成UTF-8还是乱码,郁闷我一个下午,几乎近于崩溃!后来我意识到,这个想当然cstrings的编码格式是错误的。
后来用QtCreator的帮助手册,问题出在udp的发送函数 在发送之前将QString转成QByteArray,
QString sendStr = ui->sendTextEdit->toPlainText();
QByteArray sendByteArray = sendStr.toAscii();
这里是通过.toAscii()方式转换的。转换时依据的编码方式就是setCodecForCStrings设的值,看下手册上咋说的:
QByteArray QString::toAscii () const
Returns an 8-bit representation of the string as a QByteArray.
If a codec has been set using QTextCodec::setCodecForCStrings(), it is used to convert Unicode to 8-bit char; otherwise this function does the same as toLatin1().
默认的是采用toLatin1()转换的,所以接受端无论按GB2312还是UTF-8怎么转都是乱码。而在主函数里又不能设定全局的setCodecForCStrings的编码方式。所以我最初尝试在send函数发送前,setCodecForCStrings()设成UTF-8,然后发送完后再将setCodecForCStrings()设成GB2312,发现只有第一次能发送中文,对端能正常显示。以后软键盘就乱码了。问题的根源在这里,SYSZUXpinyin的tr编码方式是GB2312,而setCodecForCStrings()这里应该是默认值,默认值多少呢?再看手册:
void QTextCodec::setCodecForCStrings ( QTextCodec * codec ) [static]
Sets the codec used by QString to convert to and from const char * and QByteArrays. If the codec is 0 (the default), QString assumes Latin-1.
默认的是Latin-1格式,也就是将codec设成0就恢复到默认状态了。用这个思路改,应该也能成功!
其实,问题的症结在toAscii()的时候依据的编码格式,能够在toAscii()之前,将QString转成UTF-8不就好了么。
将这句话QByteArray sendByteArray = sendStr.toAscii();改成QByteArray sendByteArray = sendStr.toUtf8().data();UDP的显示消息模块不变,依然用
QTextCodec *tutf=QTextCodec::codecForName("UTF-8");QString dataStr =tutf->toUnicode(data);还用UTF-8来解析,这样就能正常接收消息并显示中文了!
我后来又实验了上面的思路,在执行QByteArray sendByteArray = sendStr.toAscii(); 这句话之前,将setCodecForCStrings通过QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));设为UTF-8格式,在UDP发送函数的末尾加上,QTextCodec::setCodecForCStrings(0);将编码方式设为0,也就是默认的 Latin-1.格式,经过测试,一切正常!两种方法都可以。接收函数保持不变。
我将udp部分的send函数和receive函数贴下,大家看完整的可以看我以前的帖子:
void Widget::send() { autoScroll(); QString sendStr = ui->sendTextEdit->toPlainText(); QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8")); QByteArray sendByteArray = sendStr.toAscii(); // QByteArray sendByteArray = sendStr.toUtf8().data(); //为了配合SYSZUXpinyin输入法,这种方法也可以 QMessageBox box; if(sendStr.length()==0) { box.setText(tc->toUnicode("请输入发送内容")); box.exec(); } else if(configFlag) { udpSocket1->writeDatagram(sendByteArray, sendByteArray.length(), *remoteHostAddr, 6665); //本地发送信息再信息交互窗口的显示 QDateTime time; QString timeStr = time.currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd"); ui->getTextEdit->setTextColor(QColor("red")); ui->getTextEdit->insertPlainText(tc->toUnicode("本机") + localIpStr + ": " + timeStr + "--UDP--\n"); ui->getTextEdit->setTextColor(QColor("black")); ui->getTextEdit->insertPlainText( sendStr +"\n"); ui->sendTextEdit->clear(); //点击发送后,发送编辑框内清零 ui->sendTextEdit->setFocus(); //焦点停留在发送编辑框 autoScroll(); } else if(!configFlag) { box.setText(tc->toUnicode("请您先点击确认按钮!")); box.exec(); } QTextCodec::setCodecForCStrings(0);//为了让移植的SYSZUXpin软键盘中文显示正常,必须让CStrings恢复到默认的Latin-1编码格式 } void Widget::receive() { while(udpSocket1->hasPendingDatagrams()) { autoScroll(); QTextCodec *tutf=QTextCodec::codecForName("UTF-8"); QDateTime time; QString timeStr = time.currentDateTime().toString("yyyy-MM-dd hh:mm:ss ddd"); QByteArray data; data.resize(udpSocket1->pendingDatagramSize()); udpSocket1->readDatagram(data.data(), data.size()); //QString dataStr = QString::fromUtf8(data.data()); //这样写也是正确的 QString dataStr =tutf->toUnicode(data); ui->getTextEdit->setTextColor(QColor("red")); ui->getTextEdit->insertPlainText(tc->toUnicode("远程") + remoteIpStr+": "+ timeStr +"--UDP--\n" ); ui->getTextEdit->setTextColor(QColor("black")); ui->getTextEdit->insertPlainText(dataStr + "\n" ); autoScroll(); }
总结下:
1,SYSZUXpinyin官方只说是用GB2312编码,实际没有说全,他的tr要设成GB2312,而CStrings不用设,保留默认,其实是QString默认的Latin-1格式。而这个格式直接影响QString转QByteArray的编码格式,这个格式搞不对,在接收端就像没娘的熊瞎子,乱试就是显示不了正常的中文。
2,QString与QByteArray的转换
QString string;
QByteArray data;
data = string.toAscii(); //按照setCodecForCStrings()的格式进行转换
sendStr.toLatin1().data(); //如果转换格式未设置,则上面的转换等同于此,即按默认的Latin1格式转换
data = string.toUtf8().data(); //按UTF-8格式
QByteArray转QString:
QByteArray encodedString = "xxx";
QTextCodec *tc = QTextCodec::codecForName("UTF-8");
QString string = tc->toUnicode(encodedString);
3,其实现在我们再想想,如果UDP发送端对setCodecForCStrings不设UTF-8,
直接data = string.toAscii(); 让他按照默认的setCodecForCStrings()方式Latin-1进行转。
在接收方得到QByteArray之后,按照QTextCodec *tc = QTextCodec::codecForName("Latin1");
进行转换QString,得到Latin1编码格式的QString,再对QString的data数据进行UTF-8转换,
应该也能正常显示中文!
结论:
移植SYSZUXpinyin的注意了,为了让SUSZUXpinyin的软键盘正常拼出中文,
CStrings的编码格式一定要设成默认的Latin1格式,同时tr设成GB2312.
看来我们解决问题,一定要理清头绪,多看软件的英文参考文档,
从原理出发去解决,往往事半功倍!