2014-04-04 139 views
2

我有一個QTableView與關聯的QAbstractTableModel,其中包含某些列中的目錄名稱。我想用QFileDialog作爲編輯器來更改這些列。這有點不尋常,因爲編輯不會進入表格單元(沒有足夠的空間)。QFileDialog作爲TableView的編輯器在失去焦點時關閉

我用工作的基礎知識QStyledItemDelegate

class DirectorySelectionDelegate(QStyledItemDelegate): 

    def createEditor(self, parent, option, index):   
     editor = QFileDialog(parent) 
     editor.setFileMode(QFileDialog.Directory)  
     editor.resize(400, 400) 
     return editor 

    def setEditorData(self, editor, index): 
     val = index.model().data(index, Qt.DisplayRole) 
     fs = val.rsplit(os.path.sep, 1) 
     if len(fs) == 2: 
      bdir, vdir = fs 
     else: 
      bdir = "." 
      vdir = fs[0] 

     editor.setDirectory(bdir)   
     editor.selectFile(vdir)      

    def setModelData(self, editor, model, index): 
     model.setData(index, editor.selectedFiles()) 

當雙擊它開始QFileDialog細胞,我可以選擇我想要的目錄和選擇它在模型中設置。

但是,如果因爲某種原因QFileDialog失去焦點,它將被關閉,並且數據將被設置爲原始值。我寧願將對話框打開,直到用戶單擊「取消」或「選擇」,但我找不到這樣做的方法。

獎金問題:由於某種原因,對話忽略了resize()調用並啓動非常小(這使得失去焦點的可能性更大)。我怎樣才能改變對話框的大小?

回答

3

這是預期的行爲。

標準視圖不是小部件的容器,每個單元格在必要時繪製。只有在生成編輯觸發器時,纔會創建用於編輯的小部件並將其疊加到視圖頂部。然後調用該委託來創建適當的編輯小部件,並將該單元的位置和大小作爲參數傳入。

該視圖保留了編輯器小部件的所有權,因爲每當焦點丟失時,顯然無法再編輯,因此視圖會刪除編輯器。

如果您沒有通過setModelData函數返回任何東西,模型將不會更新。說模型回到原始數據是不正確的,因爲它從來沒有被改變過。

我建議您嘗試設置QFileDialog以模態方式打開(editor.setModal(true)),以便在將焦點轉移到另一個小部件之前必須關閉對話框。

+0

感謝您的快速回答!我試過了,它有一點幫助,它不會將焦點重新提交給我的應用程序,但如果另一個應用程序獲得焦點,編輯器仍然關閉。但聽起來這就是它應該做的,所以我必須忍受它。 – DirkR

+0

關於'setModelData':如何判斷對話是否用Choose或Cancel關閉?在這兩種情況下,調用setModelData具有相同的值。困惑... – DirkR

+0

通過檢查你從'QDialog :: result()' – RobbieE

相關問題