关于前后台通讯这一点,我在文章 QWorker技巧之作业与主线程之间通讯 中对此进行了一些说明,但一直没有给出单独的示例。因此在群里,许多朋友对QWorker如何和前台线程通讯还是有点犯迷糊。所以,我特意写了一个小演示程序,来演示如何做到这一点。 这个示例在主线程中是要分别更新10个进度条的进度信息,先看一下截图: 声
月度归档: 2014年11月
QWorker的For并行计算为什么不支持主线程作业?
首先,我们要理解下为什么要使用For进行并行计算? 当然是要充分利用现代计算机的多线程处理能力,以加快数据的处理速度! 那么问题来了,我们如果要求For计算的处理函数在主线程中计算,会发生什么现象? 很明显,在单一的线程中肯定扯不到并行计算,只能是一个一个的挨个执行。这是因为并行计算实际上是调用的同一个函数,而你显然不
利用QJson转换FireDAC数据JSON格式
首先我们来看FireDAC的数据对象,看看它的内部保存的方式。 FireDAC数据保存,大致流程如下: “TFDDataSet.InternalSaveToStorage” -》“TFDDatSManager.InternalSaveToStorage” -》“TFDDatSTable.InternalSa
[转]封三郎-利用QJSON将FDQuery转成JSON串
服务器要支持Http协议,打算采用Http+JSON的方式来交换数据。一开始考虑使用superobject,因为以前使用比较多,比较熟悉。 代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
class function FDQueryToSJSON(aQuery : TFDQuery) : string; class function TFDQueryJSONReflect.FDQueryToSJSON(aQuery: TFDQuery): string; var sj,aj,sj2,aj2:ISuperObject; i:Integer; Fieldtyp,JsonTyp:string; List:TStringList; aField : TField; Fields : string; begin // 得到一个JSON对象 sj := SO(); //创建列 aj := SA([]); List := TStringList.Create; try List.Sorted := True; Fields := '{'; for i := 0 to aQuery.FieldCount - 1 do begin sj2 := SO(); GetFieldTypeInfo(aQuery.Fields[i],Fieldtyp,JsonTyp); sj2.S[cstFieldName] := aQuery.Fields[i].FieldName; sj2.S[cstFieldType] := Fieldtyp; sj2.S[cstJsonType] := JsonTyp; sj2.I[cstFieldSize] := aQuery.Fields[i].Size; sj2.B[cstRequired] := aQuery.Fields[i].Required; sj2.I[cstFieldIndex] := aQuery.Fields[i].Index; aj.AsArray.Add(sj2); List.Add(aQuery.Fields[i].FieldName+'='+JsonTyp); Fields := Fields+aQuery.Fields[i].FieldName+':'+'0'+','; end; Fields := Fields.TrimRight([',']); Fields := Fields+'}'; sj.O['Fields'] := SO(Fields); sj.O['Cols'] := aj; //创建数据集的数据 aQuery.DisableControls; aQuery.First; aj2 := SA([]); while not aQuery.Eof do begin sj2 := SO(); for i := 0 to List.Count - 1 do begin aField := aQuery.Fields.FindField(List.Names[i]); if VarIsNull(aField.Value) then sj2.O[aField.FieldName] := SO(Null) else begin CreateJsonValueByField(sj2,aField); end; end; aj2.AsArray.Add(sj2); aQuery.Next; end; sj.O['Data'] := aj2; Result := sj.AsString; finally List.Free; aQuery.EnableControls; end; end; |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
class function CreateJsonValueByField(Json:ISuperObject;Field:TField):Boolean; overload; class function TFDQueryJSONReflect.CreateJsonValueByField(Json: ISuperObject; Field: TField): Boolean; begin Result := False; if (Field Is TDateTimeField) or (Field is TSQLTimeStampField) then Json.O[Field.FieldName] := SO(Field.AsDateTime) else if Field is TBlobField then Json.S[Field.FieldName] := EncodeString(Field.AsString) else Json.O[Field.FieldName] := SO(Field.Value); Result := True; end; |
这样写,没问题,可以得
Web格式与TColor类型的转换函数
支持#RRGGBB样式的Web字符串颜色格式的颜色值和TColor之间进行相互转换,从Web颜色格式转换为TColor类型的值时,支持省略前面的#号。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 |
type TRGBAColor = record case Integer of 0: (Red, Green, Blue, Alpha: Byte); 1: (Color: TColor); end; //从TColor到Web颜色格式 function FormatWebColor(AColor: TColor): String; var ARef: TRGBAColor absolute AColor; begin Result := '#' + IntToHex(ARef.Red, 2) + IntToHex(ARef.Green, 2) + IntToHex(ARef.Blue, 2); end; //从Web颜色格式转换为TColor function FromWebColor(const S: String): TColor; var p: PWideChar; R, G, B: Integer; begin p := PWideChar(S); if p^ = '#' then Inc(p); Result := clNone; if TryStrToInt('$' + Copy(p, 0, 2), R) then begin Inc(p, 2); if TryStrToInt('$' + Copy(p, 0, 2), G) then begin Inc(p, 2); if TryStrToInt('$' + Copy(p, 0, 2), B) then Result := RGB(R, G, B); end; end; end; |
用法当然足够简单,如 FromWebColor(‘#FF0000’)直接就是红
[协议]常用数据库直接协议(MSSQL、PostgreSQL、Oracle、MySQL)
竟然公开了,不易呀。既然微软好不容易这么大方一会,回头QDAC考虑加上对TDS协议的支持。 目前搜集到的直接连接协议,将来QDAC中的QDB可以直拨这些协议的规范,直接通过Socket连接到服务器,然后与数据集对象交互: 【PostgreSQL】 类型:官方正式文档 地址:http://www.postgresql.o
QWorker演示-正余弦曲线动态绘制示例解析
这个示例主要是演示了Delay函数的用法,示例中用Delay来作一个延迟作业,在每次作业时绘制一段曲线,从而形成动态效果。 程序运行最终的效果如图所示: 首先,我们放置了一个TChart对象,并预定义了两个TLineSeries类型的图表项目,我们在操作时,以线来拟合成正余弦曲线。 当我们点击开始按钮时,
[脚本]MSSQL在全库中查找指定的内容出现的表及字段
这个不是全文索引,所以不要指望什么特别高的效率。这个主要的目的是用于在全库检索指定的值,看看是在那个表的那个字段里。但肯定要比人工一项项找快的多,测试库是一个运行多年的HIS库,里面数据量为3.6G左右,实测用时1分37秒。这个脚本的基本原理是动态构建SQL脚本,在特定类型的数据列(这里是文本类型的字符列:char /
QWorker更新-修正了Delay作业在特定情况下不会被正常触发的问题
【问题描述】 该问题是由于TQWorker.WaitSignal函数未正确检测超时是否是由于延迟时间到达引起而造成的,这会造成在特定情形下,延迟的作业无法被及时触发。 【严重级别】 高 【更新级别】 推荐
示例-QJson中结点的查找与遍历方法小结
1、查找结点 QJson提供了一组函数来查找某一个结点,我们在下面来分别看一下:
1 2 3 4 5 6 7 |
function ItemByName(AName: QStringW): TQJson; overload; function ItemByName(const AName: QStringW; AList: TQJsonItemList;ANest: Boolean = False): Integer; overload; function ItemByRegex(const ARegex: QStringW; AList: TQJsonItemList;ANest: Boolean = False): Integer; overload; function ItemByPath(APath: QStringW): TQJson; function IndexOf(const AName: QStringW): Integer; function FindIf(const ATag: Pointer; ANest: Boolean;AFilter: TQJsonFilterEventA): TQJson; function FindIf(const ATag: Pointer; ANest: Boolean;AFilter: TQJsonFilterEvent): TQJson; overload; |
(1)此函数用于在当前结点下查找指定名称的子结点,如果指不到,返回NIL/NULL。如果要确保结点存在,用ForcePath来代替此函数。 [crayon-6004a688
QJson示例-向QJson实例中添加子结点的方法小结
QJson中添加结点主要有以下3种方式: 1、用Add函数 如我们要添加一个字符串类型的子结点:
1 2 3 4 5 6 7 8 |
var AJson:TQJson; begin AJson:=TQJson.Create; AJson.Add('Name').AsString:='Jony smith'; ... FreeAndNil(AJson); end; |
Add函数有很多重载形式,我们先大概了解一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
function Add(ANode: TQJson): Integer; overload; function Add: TQJson; overload; function Add(AName, AValue: QStringW;ADataType: TQJsonDataType = jdtUnknown): Integer; overload; function Add(const AName: QStringW; AItems: array of const): TQJson; overload; function Add(AName: QStringW; ADataType: TQJsonDataType): TQJson; overload; function Add(AName: QStringW; AValue: Extended): TQJson; overload; function Add(AName: QStringW; AValue: Int64): TQJson; overload; function Add(AName: QStringW; AValue: Boolean): TQJson; overload; function Add(AName: QStringW; AChild: TQJson): Integer; overload; function AddArray(AName: QStringW): TQJson; overload; function AddDateTime(AName: QStringW; AValue: TDateTime): TQJson; overload; function AddVariant(AName: QStringW; AValue: Variant): TQJson; overload; function Add(AName: QStringW): TQJson; overload; virtual; |
(1)是直接添加一个Json结点到当前结点
QMapSymbols更新-修正了与C++ Builder生成的Map文件的兼容性问题
【问题描述】 在加载C++ Builder生成的map文件时,由于生成的函数映射小节的内容中的函数名包含空格,如下:
1 2 3 4 5 6 7 |
0001:000098C8 __fastcall Qmapsymbols::DisableDeadlockCheck() 0001:00009894 __fastcall Qmapsymbols::EnableDeadlockCheck() 0001:000088D8 __fastcall Qmapsymbols::EnumWaitChains() 0001:00009924 __fastcall Qmapsymbols::Finalization() 0001:000062DC __fastcall Qmapsymbols::LocateSymbol(const void *, Qmapsymbols::TQSymbolLocation&) 0001:000066C8 __fastcall Qmapsymbols::StackByThreadHandle(unsigned int) 0001:00006394 __fastcall Qmapsymbols::StackByThreadId(unsigned int) |
原来处理时,使用的是取首个单词,造成没有正确解析函数名。新版本修正了这一问题。 【严重程度】 高 【更新级别】 建议
QMsgPack更新-修改了ToRtti.ToArray的代码,在未找到类型信息时抛出更明确提示
【更新内容】 修改了ToRtti.ToArray的行为,加入数组子类型的检测,并在找不到子类型时,给出更明确的提示,告知如何解决这一问题。 【更新级别】 可选 【特别感谢】 志文2014
QJson更新-修改了ToRtti.ToArray的代码,在未找到类型信息时抛出更明确提示
【更新内容】 修改了ToRtti.ToArray的行为,加入数组子类型的检测,并在找不到子类型时,给出更明确的提示,告知如何解决这一问题。 【更新级别】 可选 【特别感谢】 志文2014
QWorker更新-修正了移动平台下对象做作为AData参数时自动释放的问题
【问题描述】 在移动平台下,FMX自动管理对象的生命周期,但赋值给一个无类型指针时,对象并不会自动增加引用计数,造成对象会意外释放。 【严重级别】 高 【更新级别】 推荐 【特别感谢】 恢弘
QJson/QMsgPack RTTI 注意事项
在Delphi截止XE7的实现中,RTTI信息也并不是特别完美,所以在特定的情况下是无法获取到相应的RTTI信息,目前已知: 1、在implementation中的声明没有RTTI信息,所以你要使用ToRtti/FromRtti/ToRecord/FromRecord等函数,你必需保证用到的类型声明的interface
关于SimpleMsgPack中swap引发的问题大端法和小端法研究笔记
今天diocp裙中[珠海]-芒果反应了一个关于SimpleMsgPack的问题 msgPack.AsFloat = 2.507182; 经过编码再解码后,会直接触发异常。 因为msgPack的标准,在打包的数据是大端法IEEE 754 下面是msgPack的标准说明 [crayon-6004a688947
QMsgPack更新-增加几个函数并修改AsString的行为
【更新内容】 1、加入ValueFromStream/ValueFromFile/StreamFromValue/StreamFromFile函数,以更方便的赋二进制数据; 2、修改 AsString行为,改为返回标准的JSON字符串,MsgPack中如果映射的名字未指定,则在AsString时自动指定为空白字符。 【
QJSON更新-增加AsBytes属性及几个辅助函数
【更新内容】 1、 加入AsBytes属性,以支持二进制数据类型,默认实现直接使用的十六进制字符串表达,上层可以重载OnQJsonEncodeBytes和OnQJsonDecodeBytes事件来替换为自己的实现(如ZLib+Base64)
1 2 3 4 5 6 7 8 |
var ABytes:TBytes; AJson:TQJson; ... AJson.Add('Bytes').AsBytes:=ABytes; ... ABytes:=AJson.ItemByName('Bytes').AsBytes; |
2、 加入V
CSV格式的官方标准文档-RFC4180
这个直接上链接吧:http://tools.ietf.org/html/rfc4180