声明:由于其它原因,只谈思路,具体实现还要靠自己在实际开发中总结
在写这个之前,一直在想叫什么标题比较合适
先说一下现象。以前自己写过程序,也看过别人写的程序,感觉代码比较长(个人觉得代码多维护比较麻烦,当然代码多少与业务逻辑有关),我说的长是指:在实现同样功能的情况下,它本身有很大的精简空间。由于对数据存储的认识不同,造成的大量精力在为数据存储,数据同步及数据显示写很多逻辑。
由于不同的数据打过多年的交道,特别欣赏数据库精简的接口调用,常用的大概就select, update, delete, insert, commit。自己也想实现这样的类似的接口,以便写程序时不要为数据花太多精力。
自己在刚接触QT时,也是先看MVC模式,感觉QT把MVC发挥得淋漓尽致。随着时间的推移,发现MVC结构还是比较俗套,有点按步就班的感觉,在这种模式下代码精简下来也不是一件容易的事。后来就把MVC模式改成xxTable(xxWidget)模式,不再理会其中的Model、View怎么结合的了。但这样也有一个问题,就数据传递、同步问题。当存在多个xxTable(xxWidget)时,它们之间需要数据同步显示,于是写了个itemList。这个itemList类似一栋大厦,可以自由向上增加(记录Item数量),每层也能水平自由增加(Item中的字段),不用关心每层需要对齐问题,说得通俗一点就类似Table结构,只是每条记录Item中的字段不受约束,可自己更改。记录中的每个节点是parent->self->children关系,也就说每个节点都可以向上找到root_node节点,由root_node可以遍历所有的节点。大概就这样的一个立体结构。
这个类提供了常用接口setData,getData,setItemData, getItemData还有其它的呢,当然还有,不过个人常用的就setData,getData,setItemData, getItemData(代名词),可能是以前用java用习惯了而采用这样的命名
前两个用于key->value结构,后两个用于List结构。
全图地址:http://hi.csdn.net/space-4870011-do-album-picid-668727.html
结合图例看一下在实现thinkvd video effect中的Combox的部分代码(有关数据存储):
void ImEffectWidget::slotComBox(int index) //slot 处理
{
QString text;
QColor color;
QFont font;
QObject *obj = sender();
/* 1. for crop ***************************/
if (obj->objectName() == "comboxZoom"){
doComboxValue(m_ui.comboxZoom, "effect_crop_aspect_name", index);
}
/* 2. for effect ***************************/
else if (obj->objectName() == "comboxEffect"){
doComboxValue(m_ui.comboxEffect, "filter_effect_name", index);
m_treeItem->setMediaData("filter_effect_index", index); //for player
}
/* 3. for watermark ***************************/
else if (obj->objectName() == "comboxFont"){
doComboxValue(m_ui.comboxFont, "effect_item_font_family", index, true);
}else if (obj->objectName() == "comboxColor"){
doComboxValue(m_ui.comboxColor, "effect_item_color", index, true);
}else if (obj->objectName() == "comboxSize"){
doComboxValue(m_ui.comboxFont, "effect_item_font_size", index, true);
}else if (obj->objectName() == "comboxStyle"){
slotChangeStyle(index);
}
/* 5. for subtitle ***************************/
else if (obj->objectName() == "comboxSTCodec"){
text = m_ui.comboxSTCodec->itemText(index);
m_treeItem->setMediaData("effect_subtitle_codec", text);
}else if (obj->objectName() == "comboxSTFrontColor"){
doComboxValue(m_ui.comboxSTFrontColor, "effect_subtitle_front_color", index);
}else if (obj->objectName() == "comboxSTBackColor"){
doComboxValue(m_ui.comboxSTBackColor, "effect_subtitle_back_color", index);
}else if (obj->objectName() == "comboxSTOutlineColor"){
doComboxValue(m_ui.comboxSTOutlineColor, "effect_subtitle_outline_color", index);
}else if (obj->objectName() == "comboxSTScaleX"){
doComboxValue(m_ui.comboxSTScaleX, "effect_subtitle_scalex", index);
}else if (obj->objectName() == "comboxSTScaleY"){
doComboxValue(m_ui.comboxSTScaleY, "effect_subtitle_scaley", index);
}else if (obj->objectName() == "comboxSTFont"){
doComboxValue(m_ui.comboxSTFont, "effect_subtitle_font_family", index);
}else if (obj->objectName() == "comboxSTSize"){
doComboxValue(m_ui.comboxSTSize, "effect_subtitle_font_size", index);
}else if (obj->objectName() == "comboxSTStyle"){
slotChangeStyle(index);
}else if (obj->objectName() == "comboxSTSpacing"){
doComboxValue(m_ui.comboxSTSpacing, "effect_subtitle_spacing", index);
}else if (obj->objectName() == "comboxSTTimer"){
doComboxValue(m_ui.comboxSTTimer, "effect_subtitle_spacing", index);
}
sendEffectEvent(); //for sdl event
}
#define COLORVAL() /
if (comboxIndex < 0) return; /
ImColorComboBox *oc = qobject_cast<ImColorComboBox *>(o); /
color = oc->color(comboxIndex); /
#define FONTVAL() /
if (saveKey.indexOf("subtitle") != -1) /
fontKey = "effect_subtitle_font"; /
else /
fontKey = "effect_item_font"; /
if (bSaveList==true) { /
font = qVariantValue<QFont>(m_treeItem->mdata(fontKey)); /
}else{ /
font = qVariantValue<QFont>(m_treeItem->getDataItem(fontKey)); /
}
void ImEffectWidget::doComboxValue(QComboBox *o, const QString &saveKey, int comboxIndex, bool bSaveList)
{
QString text, dataKey, fontKey;
QFont font;
QColor color;
if (comboxIndex > -1)
text = o->itemText(comboxIndex);
else
text = o->currentText();
bool bFont = o->property("font").toBool();
bool bColor = o->property("color").toBool();
if (bFont || bColor) dataKey=QString("%1_data").arg(saveKey);
if (bFont)
{
FONTVAL();
if (text == "effect_item_font_family")
font.setFamily(text);
else if(text == "effect_item_font_size")
font.setPointSize(text.toInt());
}
if (bSaveList)
{
if (bFont){ // font
m_treeItem->setDataItem(saveKey, text);
m_treeItem->setDataItem(fontKey, qVariantFromValue<QFont>(font));
}else if(bColor){ //color
COLORVAL();
m_treeItem->setDataItem(saveKey, text);
m_treeItem->setDataItem(dataKey, qVariantFromValue(color));
}else //other
m_treeItem->setDataItem(saveKey, text);
}else{
if (bFont){
m_treeItem->setMediaData(saveKey, text);
m_treeItem->setMediaData(fontKey, qVariantFromValue<QFont>(font));
}else if(bColor){
COLORVAL();
m_treeItem->setMediaData(saveKey, text);
m_treeItem->setMediaData(dataKey, qVariantFromValue(color));
}else
m_treeItem->setMediaData(saveKey, text);
}
}
数据都保存在m_treeItem中,可用于显示,转换,播放等
这个代码也许不精简,希望有人多提意见。也可到www.thinkvd.com给我留言.