0

診断できないような非常に奇妙なバグがあります。

QSqlTableModel を使用して QTableView にデータを表示する PyQt4 アプリケーションがあります。次のように、分離されたプログラムでバグを繰り返しました。プログラムを実行すると、ほとんどのセル/列が編集可能になり、データベースが変更されます。しかし、なぜか(今回実行すると)5行目が編集できません。問題のある行は変更されているようです。

これをさらにデバッグする方法について何か提案はありますか? setData メソッドをオーバーライドしましたが、期待どおりに動作しています。新しい値が渡され、親の setData は True を返します。ただし、データベースは変更されず、tableView は古いデータに戻ります。

編集:これは PyQt4 のバグである可能性があると考えて、最新の PyQt4 (バージョン 4.10) をインストールしました。これは、問題の動作を変更するようには見えません。また、データベース クラスが含まれていないことにも気付きました。DB クラスも含めるようにコード リストを更新しました。構成ファイルからデータベース接続情報を取得しています。基本的に、MySQL5 サーバー バックエンドを使用しているだけです。

class Database:
    def __init__(self, parent = None):
        print "Opening database connection."
        self.data = QtSql.QSqlDatabase.addDatabase("QMYSQL")
        self.data.setHostName(parent.config.get('Database','mysql_server'))
        self.data.setPort(int(parent.config.get('Database','mysql_port')))
        self.data.setDatabaseName(parent.config.get('Database','mysql_database'))
        self.data.setUserName(parent.config.get('Database','mysql_user'))
        self.data.setPassword(parent.config.get('Database','mysql_pass'))

        if not self.data.open() :
            print "error opening database"
            print self.data.lastError().text()

        print "database init complete"


class Model(QtSql.QSqlTableModel):

    def __init__(self, prjID, parent = None):
        super(Model, self).__init__(parent)
        self.setEditStrategy(QtSql.QSqlTableModel.OnRowChange)

        self.setTable("Debug")


        self.setFilter("PrjID = " + str(prjID))

        if not self.select() :
            print "error, ", self.lastError().text()




class Main(QtGui.QMainWindow) :
    def __init__(self) :
        QtGui.QMainWindow.__init__(self)

        self.config = ConfigParser.ConfigParser()
        self.config.read("default.cfg")
        self.db = Database(self)
        self.model = Model(39,self)        
        self.tableView = QtGui.QTableView(self)
        self.tableView.setGeometry(0,0,4000,400)


        self.tableView.setModel(self.model)



if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    MainWindow = Main()  #QtGui.QMainWindow()
    #ui = Ui_MainWindow()
    #ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

そして、これが私が作成したデバッグテーブルです。上記のように、バックエンド DB は MySQL です。このテーブルを定義する方法に何か問題があるのでしょうか?:

CREATE TABLE IF NOT EXISTS `Debug` (
  `ID` int(11) NOT NULL AUTO_INCREMENT,
  `PrjID` int(11) DEFAULT NULL,
  `WorkType` int(11) DEFAULT NULL,
  `Qty` double DEFAULT NULL,
  `UnitCost` double DEFAULT NULL,
  `Note` varchar(256) DEFAULT NULL,
  `ShowDetail` tinyint(1) NOT NULL,
  `SubTotal` float DEFAULT NULL,
  UNIQUE KEY `ID` (`ID`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=101 ;

--
-- Dumping data for table `Debug`
--

INSERT INTO `Debug` (`ID`, `PrjID`, `WorkType`, `Qty`, `UnitCost`, `Note`, `ShowDetail`, `SubTotal`) VALUES
(1, 37, 10, 66, 1, 'asdfasdf', 1, 66),
(2, 37, 7, 22, 2, 'asdfasdf', 1, 44),
(3, 37, 11, 11, 33, 'asdfasdf', 1, 363),
(4, 37, 7, 1, 10, 'asdfasdf', 1, 10),
(5, 37, 10, NULL, NULL, 'aa', 0, NULL),
(100, 39, 6, 8, 10, 'aa', 0, 80),
(6, 38, 10, 2151, 0.20000000298, NULL, 0, 430.2),
(7, 38, 27, 120.25, 0, '123', 1, 0),
(8, 38, 22, 5.69, 5, NULL, 0, 28.45),
(9, 38, 7, 3, 35, NULL, 1, 105),
(11, 39, 1, 6, 35, 'aa', 0, 210),
(12, 39, 17, 17.78842, 6.5, 'zz', 0, 115.625),
(13, 39, 27, 147.944803, 0, 'zz', 0, 0),
(14, 39, 28, 82.17064, 15, NULL, 0, 1232.56),
(15, 39, 30, 64.42334, 0, 'aa', 0, 0);
4

1 に答える 1

1

考えられる説明:私が理解したことがいくつかあります。私の基本的な問題は、私のテーブルが主キーを定義していないことだと思います。UNIQUE KEY の代わりに PRIMARY KEY を使用してテーブルを作成すると、問題は解決します。

PyQt4 に関する限り、QSqlTableModel の removeColumn ではなく、QTableView の setColumnHidden メソッドを使用して列 (ID 列など) を非表示にする必要があることも学びました。ID 列 (主キー) が削除されると、更新が面倒になります。

また、ビューを使用している場合 (MySQL の要求に応じてビューを編集可能にする必要がある場合)、QSqlTableModel で主キーを手動で設定する必要があることも確認しました。例えば:

pk = QtSql.QSqlIndex("cursName","idxName")
pk.append(QtSql.QSqlField("ID"))
self.setPrimaryKey(pk)
于 2013-03-08T04:27:48.730 に答える