2016-12-30 91 views
0

正確取消選中Qtablewiget中的項目我創建了一個包含三列的表格窗口小部件。該表位於qwizard內部。它通過讀取文件並將該文件的行放入第一列來填充。它看起來像下面的圖片。基本上,我想程序的行爲是這樣的:如何根據條件

  1. 如果兩個remove half of itemremove all of item進行檢查,取消remove half of item只留下remove all of item爲row​​.Then行添加到文件中。

    按OK按鈕

  2. 否則,如果只remove half of itemremove all of item檢查執行它。將該行添加到文件中。

    按OK按鈕

的問題是,它與我的期望輸出結束了,但只有當我按OK多次 處理該行爲的功能執行它是def print_checked(self):def setChoice(self, item):

enter image description here

from PyQt4 import QtCore, QtGui 
import sys 

class TablePage(QtGui.QWizardPage): 
    def __init__(self, parent=None): 
     super(TablePage, self).__init__(parent) 
     self.isWrittenTo = False 
     self.table = QtGui.QTableWidget() 
     self.table.setGeometry(200, 200, 200, 200) 

     self.configureTable(self.table) 
     self.table.verticalHeader().hide() 

     self.buttonBox = QtGui.QDialogButtonBox(self) 
     self.buttonBox.setOrientation(QtCore.Qt.Horizontal) 
     self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel | QtGui.QDialogButtonBox.Ok) 

     self.horizontalLayout = QtGui.QHBoxLayout() 
     self.verticalLayout = QtGui.QVBoxLayout(self) 
     self.horizontalLayout.addWidget(self.table) 
     self.verticalLayout.addLayout(self.horizontalLayout) 
     self.verticalLayout.addWidget(self.buttonBox) 
     self.buttonBox.accepted.connect(self.print_checked) 
     self.buttonBox.rejected.connect(self.close) 
     self.choice = [] 

     self.table.itemChanged.connect(self.setChoice) 




    def configureTable(self, table): 
     rowf = 0 
     rowx = 0 
     table.setColumnCount(3) 
     table.setHorizontalHeaderItem(0, QtGui.QTableWidgetItem("Whole items")) 
     table.setHorizontalHeaderItem(1, QtGui.QTableWidgetItem("remove half of item")) 
     table.setHorizontalHeaderItem(2, QtGui.QTableWidgetItem("remove all of item")) 
     header = table.horizontalHeader() 
     header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents) 
     header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents) 
     table.horizontalHeader().setStretchLastSection(True) 
     item_list = [] 

     with open("/home/test1/items.txt") as in_file: 
      if in_file is not None: 
       xvar = in_file.readlines() 
      for line in xvar: 
       item_list.append(line) 
       rowf += 1 

     table.setRowCount(rowf) 

     for linex in item_list: 
      x = QtGui.QTableWidgetItem() 
      table.setItem(rowx, 0, x) 
      rowx += 1 
      x.setText(linex) 
     for column in range(3): 
      for row in range(rowf): 
       if column % 3: 
        self.item = QtGui.QTableWidgetItem(column) 
        self.item.setFlags(QtCore.Qt.ItemIsUserCheckable | 
            QtCore.Qt.ItemIsEnabled) 
        self.item.setCheckState(QtCore.Qt.Unchecked) 
        self.item.setTextAlignment(QtCore.Qt.AlignHCenter) 
        table.setItem(row, column, self.item) 

    def setChoice(self, item): 
     if item.checkState() == QtCore.Qt.Checked: 
      self.choice.append(item) 
     if item.checkState() == QtCore.Qt.Unchecked: 
      self.choice.remove(item) 

    def print_checked(self): 
     path = '/home/test1/items-to-mod.txt' 
     mode = 'a' if self.isWrittenTo else 'w' 
     user = self.table 
     if len(self.choice) > 0: 
      with open(path, mode) as f: 
       for item in self.choice: 
        delete = user.horizontalHeaderItem(item.column()).text() 
        if delete == "remove all of item" and user.item(item.row(), 1).checkState() == QtCore.Qt.Checked: 
         user.item(item.row(), 1).setCheckState(QtCore.Qt.Unchecked) 
         print ('%s' % user.item(item.row(), 0).text() + 'is marked for %s' % delete) 
         f.write('fully remove %s' % user.item(item.row(), 0).text()) 
        elif delete == "remove half of item": 
         print ('%s' % user.item(item.row(), 0).text() + 'is marked for %s' % delete) 
         f.write('remove half of %s' % user.item(item.row(), 0).text()) 
        elif delete == "remove all of item": 
         print ('%s' % user.item(item.row(), 0).text() + 'is marked for %s' % delete) 
         f.write('fully remove %s' % user.item(item.row(), 0).text()) 
        else: 
         print('%s' % item.text()) 
         print (item.row(), item.column()) 


if __name__ == '__main__': 
    app = QtGui.QApplication(sys.argv) 
    wizard = QtGui.QWizard() 
    tablepage = TablePage() 
    wizard.addPage(tablepage) 
    wizard.button(QtGui.QWizard.NextButton).clicked.connect(tablepage.print_checked) 
    wizard.show() 
    sys.exit(app.exec_()) 
+0

我無法理解您的要求。在這兩種情況下是添加到文件的行?在第一種情況下:是否僅在刪除一半項目時才移除支票? – eyllanesc

+0

是的,該行被添加到文件中,但我必須一直按Ok按鈕才能在文件中顯示正確的輸出 – answerSeeker

+0

另一件事是,如果您知道一種將表格單元格中的複選框居中的方法太棒了 – answerSeeker

回答

1

在你的代碼中重複動作時未選中,使改進代碼成爲可能的輸出:如果標記爲第一個添加1 = 2 ** 0,如果標記爲第二個添加2 = 2 ** 1,那麼會有僅是每行4例:[0,2 ** 0,2 ** 1,** 2 0 + 2 ** 1] = [0,1,2,3]

變化:

def print_checked(self): 
     path = '/home/test1/items-to-mod.txt' 
     mode = 'a' if self.isWrittenTo else 'w' 
     user = self.table 
     d = dict([(x, 0) for x in range(self.table.rowCount())]) 

     for item in self.choice: 
      d[item.row()] += 2 ** (item.column() - 1) 

     text = "" 
     for row, value in d.iteritems(): 
      if value == 3: # They are both checked 
       print("fully remove %s" % user.item(row, 0).text()) 
       user.item(row, 1).setCheckState(QtCore.Qt.Unchecked) 
       text += 'fully remove %s' % user.item(row, 0).text() 
      elif value == 2: # only second is checked 
       print('fully remove of %s' % user.item(row, 0).text()) 
       text += 'fully remove %s' % user.item(row, 0).text() 
      elif value == 1: # only first is checked 
       print("remove half of %s" % user.item(row, 0).text()) 
       text += 'remove half of %s' % user.item(row, 0).text() 

     with open(path, mode) as f: 
      f.write(text) 

輸出:

enter image description here

單擊確定後:

enter image description here

fully remove a 

fully remove of b 

remove half of c 
+2

你應該解釋OP做錯了什麼,理想情況下(也就是說,如果可能的話,也就是說只改變了幾個代碼塊)只發布需要改變的代碼,因爲SO不支持並排比較。 – Schollii

+0

它完全按照我喜歡的方式工作,但是您可以解釋這一行代碼的工作原理嗎?我有一個想法,但不完全確定'd = dict([(x,0)爲範圍內的x(self.table.rowCount())]) 對於self.choice中的項目: d [item.row )] + = 2 **(item.column() - 1)' – answerSeeker

+1

A ** k = {a * a * a * ... * a} k次 – eyllanesc

1

我會改變的第一件事是setChoice:它應該反映的地位更加明確,通過存儲有至少一個檢查,狀態各行:一半(1),全(2),或兩者(1 + 2 = 3):

def setChoice(self, item): 
    row = item.row() 
    if item.checkState() == QtCore.Qt.Checked: 
     self.choice.setdefault(row, 0) 
     self.choice[row] += item.column() 
     print(item, row, self.choice[row]) 

    else: 
     assert item.checkState() == QtCore.Qt.Unchecked 
     self.choice[row] -= item.column() 
     print(item, row, self.choice[row]) 
     # if checked state is now 0, remove it (could instead leave it 
     # but filter on checked==0 in print_checked): 
     if self.choice[row] == 0: 
      del self.choice[row] 

這需要一些改變print_checked。有很多方法可以做到這一點,但我喜歡讓代碼反映意圖:您需要「修復」或「調整」有2個複選標記的行;然後照常處理。我還簡化了一些格式字符串。結果是:

with open(path, mode) as f: 
    for item_row, checked in self.choice.items(): 
     item_text = user.item(item_row, 0).text() 
     if checked == 3: # delete == "remove all of item" and user.item(item.row(), 1).checkState() == QtCore.Qt.Checked: 
      # need to fix it! 
      item_half = user.item(item_row, 1) 
      item_half.setCheckState(QtCore.Qt.Unchecked) 
      checked = 2 
      f.write('fixing %s\n' % item_text) 

     delete = user.horizontalHeaderItem(checked).text() 
     if checked == 1: # delete == "remove half of item": 
      f.write ('%s is marked for %s\n' % (item_text, delete)) 
      f.write('remove half of %s\n' % item_text) 

     elif checked == 2: # delete == "remove all of item": 
      f.write ('%s is marked for %s\n' % (item_text, delete)) 
      f.write('fully remove %s\n' % item_text) 

     else: 
      f.write('%s\n' % item_text) 
      f.write(item_row, checked) 
+0

@ Schollii謝謝 – answerSeeker