Qt 表格&列表數據驅動化(c++) 原創


一、 Qt表格&列表 展示效果描述化與數據綁定驅動化

 

調用及解說如下:

	QStringList formats;
        formats.append("0~股票代碼~code~~72~~|");
        formats.append("0~股票名稱~name~~180~~|");

        formats.append("1~現價~AnimalCell~1|3~64~~zjcj|zdf");
        formats.append("1~漲跌幅~AnimalCell~0|2|1~72~~zdf|zdf");
        formats.append("1~行業力道~AnimalCell~0|2|0|blue~72~~hyld|black");

        formats.append("1~漲跌分布~ChangeBar~~128~~up|up5|down|down5");
        formats.append("1~短期強弱~RatingBar~~118~~oldhysrps|hysrps");
        formats.append("1~狀態~ZdBar~~32~~zdf");
        formats.append("1~綜合~ZhpmBar~~32~~zjcj|hysrps");
        formats.append("1~分析師~ZhpmBar2~~42~~hysrps");

        formats.append("1~市凈率~AnimalCell~0|2|0|black~72~~P/E|black");
        formats.append("1~行業力道~AnimalCell~0|2|0|black~72~~P/B|black");
        formats.append("1~市現率~AnimalCell~0|2|0|black~72~~P/S|black");
        formats.append("1~市銷率~AnimalCell~0|2|0|black~72~~P/CF|black");

	//ui->tableWidget 表示QTableWidget控件,該控件雖然傳統但非常靈活,QTableView雖然可以使用數據模型,但展示需要重繪,意味着要寫不少代碼且需要編譯,這是我選擇前者的原因。
	//pMRS是數據集,是一個二維表,可以具有任意行列及其數據
	//CommonStudio::AutoBindingToDataGrid函數只需要傳入QTableWidget、約定數據,描述信息,即可將約定數據按照描述信息來展示。
        CommonStudio::AutoBindingToDataGrid(ui->tableWidget, pMRS,formats,this);

  如上所圖及解說所示,只需要寫好描述信息formats,將QTableWidget控件、數據集以及描述信息傳入CommonStudio::AutoBindingToDataGrid函數,即可實現上圖所展示的效果。進一步講,請求回來的相同數據集,不同描述信息,展示效果不同。

  對於理財產品(終端),或者說所有的應用程序來說,表格是很常見的,可動不動就要寫和修改代碼並且編譯和讓用戶升級是很累的事情,本文這樣的做法,可以將描述信息存在后台(數據庫中),這樣需求發生更改時,修改數據庫中對應描述即可。其二,只要維護一處,處處都可以得到更新,隨時控件資源的開發和擴展,展示出來的效果和功能將會更加豐富和強大。

二、傳統表格數據裝載與展示

//構造函數里初始化表格&列表
MyWidget::MyWidget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::MyWidget)
{
    ui->setupUi(this);

    this->setObjectName("Module1");

    indexTable=new QTableWidget(0,5,this);
    qsgTable=new QTableWidget(0,5,this);
    newsTable=new QTableWidget(0,3,this);
    industryTable=new QTableWidget(0,6,this);
    zhphTable=new QTableWidget(0,15,this);

    CommonStudio::InitTableWidget(indexTable,false,true);
    CommonStudio::InitTableWidget(qsgTable,false,true);
    CommonStudio::InitTableWidget(newsTable,false,true,false,false);
    CommonStudio::InitTableWidget(industryTable,true,true);
    CommonStudio::InitTableWidget(zhphTable,true,true);

    QStringList header;    
    header<<""<<tr("Name")<<tr("Zjcj")<<tr("Zd")<<tr("Zdf");//QLatin1String
    indexTable->setHorizontalHeaderLabels(header);

    header.clear();
    header<<""<<tr("Name")<<tr("Zhpf")<<tr("Zjcj")<<tr("Zdf");
    qsgTable->setHorizontalHeaderLabels(header);

    header.clear();
    header<<""<<tr("HyName")<<tr("HyZdf")<<tr("Zdfb") << tr("LzName") << tr("LzZdf");
    industryTable->setHorizontalHeaderLabels(header);

    header.clear();
    header<<""<<tr("Name") << tr("Code") << tr("Zhpf") << tr("Dqqr") << tr("Cqqr") << tr("Zjcj") << tr("Zdf") << tr("Lb")
         << tr("Hsl") << tr("Open") << tr("High") << tr("Low") << tr("Volume") << tr("Amount");
    zhphTable->setHorizontalHeaderLabels(header);

    indexTable->setColumnHidden(0,true);
    indexTable->setColumnWidth(1,66);
    indexTable->setColumnWidth(2,66);
    indexTable->setColumnWidth(3,54);
    indexTable->setColumnWidth(4,54);

    qsgTable->setColumnHidden(0,true);
    qsgTable->setColumnWidth(1,66);
    qsgTable->setColumnWidth(2,66);
    qsgTable->setColumnWidth(3,54);
    qsgTable->setColumnWidth(4,54);

    newsTable->setColumnHidden(0,true);
    newsTable->setColumnWidth(1,200);
    newsTable->setColumnWidth(2,40);

    industryTable->setColumnHidden(0,true);
    industryTable->setColumnWidth(1,200);
    industryTable->setColumnWidth(2,54);
    industryTable->setColumnWidth(3,320);
    industryTable->setColumnWidth(4,100);
    industryTable->setColumnWidth(5,54);

    zhphTable->setColumnHidden(0,true);
    zhphTable->setColumnWidth(1,88);
    zhphTable->setColumnWidth(2,64);
    zhphTable->setColumnWidth(3,64);
    zhphTable->setColumnWidth(4,114);
    zhphTable->setColumnWidth(5,114);
    zhphTable->setColumnWidth(6,88);
    zhphTable->setColumnWidth(7,88);
    zhphTable->setColumnWidth(8,88);
    zhphTable->setColumnWidth(9,88);
    zhphTable->setColumnWidth(10,88);
    zhphTable->setColumnWidth(11,88);
    zhphTable->setColumnWidth(12,88);
    zhphTable->setColumnWidth(13,88);
    zhphTable->setColumnWidth(14,88);

    ..............................................不一一例出
}
//數據回調函數,數據回來后,裝載或更新到表格&列表
void MyWidget::receiveDataSlot(int vol, ENORecordset **pMRS, QVariant etag)
{   
    ETagData realEtag;
    realEtag = etag.value<ETagData>();

    int i=0;
    int poor;
    int row= pMRS[0]->RowsAffected();
    int column = pMRS[0]->FieldCount();
    QString str;

    if(vol>=1){
        QWidget *widget;
        ZhpmBar *zhpfCtl;
        ChangeBar *changeCtl;
        RatingBar *ratingCtl;

        AnimalCell *animalCtl;
        QTableWidgetItem *item;

        pMRS[0]->FetchFirst();

        //Index hq list
        if(realEtag.nMainFunc==31000 && realEtag.nSubFunc==4)
        {
            poor = row - indexTable->rowCount();
            if(poor>0){
                for(int i=0;i<poor;i++)
                    indexTable->insertRow(indexTable->rowCount());
            }
            else if(poor<0){
                poor=qAbs(poor);
                for(int i=poor-1;i>=0;i--)
                    indexTable->removeRow(i);
            }

            double zdfD;
            char code[64],name[64],zjcj[64],zd[64],zdf[64],exchid[64];
            while(!pMRS[0]->IsEOF())
            {
                zdfD = pMRS[0]->ToFloat("zdf");
                strcpy(code,pMRS[0]->ToString("code"));
                strcpy(name,pMRS[0]->ToString("name"));
                strcpy(zjcj,pMRS[0]->ToString("zjcj"));
                strcpy(zd,pMRS[0]->ToString("zhd"));
                strcpy(zdf,pMRS[0]->ToString("zdf"));
                strcpy(exchid,pMRS[0]->ToString("exchid"));

                TCHAR tchar[64];
                ENOUtils::ToWChar(name,tchar,64);

                //key
                str.clear();
                str.append(code);
                str.append(".");
                str.append(exchid);

                item=new QTableWidgetItem(str);
                indexTable->setItem(i,0,item);

                //name
                item=new QTableWidgetItem(name);
                indexTable->setItem(i,1,item);
		
		........................這部分代碼太多,隨時根據需求會改動的,不一一列出來了

                i++;
                pMRS[0]->FetchNext();
            }
	}
   }
}

  

三、新方式與傳統做法的對比

  傳統方式下,需要不斷編寫和維護大量代碼,新方式下,開發人員只需要編寫簡單少量的描述信息,管理人員和經理人士無需開發經驗即可以通過管理定制模塊,傻瓜化的方式下選擇需要的列並設置每一列的展示效果(控件類型),以及對應的字段即可,包含展示的中文名稱、寬度、控件類型以及顏色等屬性(顏色可以是固定的,也可以像現價這樣根據漲跌度的正負號來顯示紅或綠色),就可以實現上圖效果。

  客戶端請求命令不同,就會得到不同的數據結果,新方式下,配和這樣的簡單描述,基本上可以實現各種復雜表格效果的展示和使用,隨時表格的越來越多,新方式的工作量由於傻瓜定制式模塊(類似股票選股模塊及其操作)變得輕松、簡單、快速,而傳統方式則要面對大量代碼的編寫和維護,哪個更有優越不必多說了吧?

注:“管理定制模塊”可以錄入或選擇指定功能號(主子功能及參數),然后就出來字段信息(英文是唯一的,中文則表示默認描述),用戶要展示那些就選擇那些出來,可以更新要展示時候的描述、描述、類型(比如這一列顯示為某個控件),以及該列對應到那些字段等等,操作就簡直就如選股,選好了點擊確定,還可以請求數據並把展示效果顯示出來,之后可以將這些信息保存到指定數據庫中位置。

注:就當自己在選股,選好了,作為條件入選的列作為列表的列,數據等同請求回來的內容了,就這么簡單。

注:新方式原來是在silverlight下實現過的,但sl下有各種限制,搞得描述信息復雜龐大且有限制,不過到了Qt這兒就非常靈活和好使了,不想寫太多枯燥繁雜的代碼而創。

 四、理財應用表格統計

首頁    5個表格&列表
大勢..  2個表格
個股..  至少3個表格
行業..  2個表格
機構..  2個表格(10種展示組合,條件不同,表格展示內容不同)
組織..  2個表格(5種展示組合,同上)
對沖..  2個表格
交易決策 N個表格(N表示有點多)
市場雷達 6個表格
事件..  1表多展示(2*3=6種展示組合)
中山..  3個表格
智能選股 1個表格(目前選股出來的列都是固定的,有了本文中的利器,就可以把條件包含的列展示出來,而不是每次選股出來的結果列都一樣)

如今有了這種新方式,至少在表格這一塊,不需要寫大量枯燥,讓我頭發越來越少的代碼,爽了很多。

 

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2026 CODEPRJ.COM