QTableView另類打印解決方案(複用render函數去解決print問題)

Qt QTableView另類打印解決方案 
    上回書說道Qt的model/view,我就作了個demo用於顯示數據庫中的內容。沒想到tableview的打印居然成了問題。我困惑了,難道Qt不該該提供一個print函數給tableview嗎?這是最最經常使用的功能啊。
    Google了半天,也沒什麼有用的結果。看到Qt labs有一篇blog,叫「All You Need is a little Polish」,裏面給出了最新的spreadsheet demo中的tableview print代碼。還挺高興,原來已經能夠解決了。後來試了一下,發現根本不是那麼回事,這個例子只能打印tableview當前顯示的區域,對於分頁、頁眉、頁腳、等等都不支持。原來寫這個demo的並非真正的開發人員,只是support team的。
    做爲10年的老MFCer,我有着厚臉皮的DIY精神(沒辦法,被逼的太屢次了,每次只能本身來)。相信以我在MFC中寫Doc/View printing的經驗,搞定Qt的打印仍是沒問題的。可是在跳進代碼海以前,我花了幾個小時仔細研究了一下QTableView的代碼,發現我能夠選下面幾個實現方案。
1. 鴕鳥方案
    學過操做系統的Tx都知道這意味着什麼樣的方案。上面提的那篇Blog裏的方法能夠算一種嘍。若是你打印的table每次都是在1頁內的話,能夠用這個方案。可是做爲10年英明神武的老MFCer,實在沒臉這樣作。
2. model方案
    這個方案是從model中取得全部table的數據,而後使用2個for循環將這些數據以行和列打印出來。在qt-app網站上有人給出了這個解決方案(http://qt-apps.org/content/show.php/TableView+Printer?content=76616)。我看了代碼,做者在打印每頁時從model中取數據,而後在內存中生成一個graphicview,而後用graphicview打印。也實現分頁等功能。但打印的效果很差,增長的邊框感受也很彆扭。
    還有人建議將model中的數據導入至QTextDocument中,而後利用QTextDocument稍微強大一點打印功能打印。
    總之,全部這些方案實現起來比較麻煩,並且只從model中取數據,忽略了view(delegate)中顯示相關的因素(如文字render的格式,是否被選中等等)。還有一點就是分頁老是成問題。即便縱向分頁對了,橫向的分頁仍是沒看到相應的實現。(你們都注意到在Excel中一頁橫向打不下時會將未打印的內容打印至下一頁吧)
3. delegate方案
    在QTableView代碼中,真正render每一個item時,仍是使用delegate的。因此有人建議使用delegate在2個for循環中將這些數據以行和列打印出來。這個貌似是最好的解決方案了。若是我是Qt開發人員的話,我會首選這個方案的。
4. 個人方案
    惋惜我不是Qt的開發人員(不知Nokia這種企業氛圍如何)。我的感受Qt的風格是沉穩,外加一絲靈動。因此個人方案可能不是Qt開發人員喜歡的。即便我我的也以爲這個方案難登大雅之堂。只是在時間和精力都有限的狀況下,藉助了Qt的一點Q,想出來的一個很是tricky的辦法。
其實個人方案就是:鴕鳥方案的升級版。噹噹噹。。。
個人靈感來源於上面Bolg中鴕鳥方案的4句代碼:
setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
resize(printer->width(), printer->height());
render(printer);
前面2具隱藏scrollbars,第3句,讓view與print的紙張大小相同,最關鍵的第4句,直接將view render到printer中。
做爲一個10年的老MFCer,我堅信Qt在代碼複用性方面應該更勝一籌。既然view能夠直接render到printer中(感謝Qt中painter和printer的設計),那麼爲何還須要去寫delegate的paint呢?因此,個人方案出發點就是從怎麼複用render函數去解決print問題。 
方案成功了嗎?心急的Tx請先看下面的圖片。
 
    打印預覽、橫向分頁、縱向分頁、背景色、選中標記、頁眉、頁腳。。。。。。該有的都有了。從單頁到上百頁我都測試過。那麼個人鴕鳥升級方案是怎麼實現的呢?
    其實很是簡單,仍是基於view的render函數,既然view當前顯示的內容能夠直接render到printer中,那麼我就模擬給它翻頁,而後render每頁不就好了。最初的辦法是使用QScrollBar的setValue對橫向和縱向進行翻頁。就是打完第1頁以後,翻到第2頁,再打印,以此類推。但最後一頁很難處理,若是最後一頁的內容只有幾行的話,是無法繼續向下翻得,形成的結果就是倒數第2頁不少打印過的行會再次被打印出來。難道沒辦法了。
    束手無策之際,只能繼續翻Qt的文檔,當看到tableview中setRowHidden和setColumnHidden這2個函數時,我一剎那被Carmack大仙(個人偶像)靈魂附體。這不就解決了嗎?
    什麼?你還不明白?
    打印完第1頁時,將這頁打印過的row隱藏,而後打印下一頁。打印完縱向分頁後,將橫向打印過的colum隱藏。再次打印縱向分頁(從而實現橫向分頁)。
    剩下的就是數學了。。。
    大部分問題都解決了。我寫了個QTableView的派生類MyTableView,裏面一些打印相關的代碼用到了David Johnson david@usermode.org的textprinter中某些代碼,感謝開源社區。個人MyTableView類能夠實現下面的功能:
1. WYSIWYG打印/打印預覽,這意味着每一個item的背景顏色、文字顏色、顯示屬性、選擇狀態、邊框、表頭。。。。。。全部你看到tableview顯示的,均可以原封不動直接打印出來;
2. 縱向分頁,當在一頁末尾某行沒打印全時,會自動在下一頁再次打印;
3. 橫向分頁,當在一頁右側某列沒打印全時,會自動在下一次橫向分頁時再次打印;
4. 打印頁眉
5. 打印頁腳
6. 打印邊距
7. 打印成PDF文件php

http://blog.csdn.net/superjoel/article/details/5177199數據庫

相關文章
相關標籤/搜索