首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >将数据从QTreeVIew添加到QTreeView

将数据从QTreeVIew添加到QTreeView
EN

Code Review用户
提问于 2015-06-03 15:23:05
回答 1查看 3.8K关注 0票数 6

我有一个QTreeview,其中填充了来自data_for_tree字典的数据。假设那本字典代表了一个人最常见的购物方式。我把它叫做“来源列表”。

该列表中显示的数据与“接收方列表”中显示的数据不同。假设一个人通过特殊的形式插入了它。目标是--通过点击两次,以正确的格式和适当的方式从源列表添加数据到接收者列表。

这个目标已经实现了,但在我看来,是通过非常复杂的方式实现的。首先我得到所选的项目,然后将它们与data_for_tree字典进行比较,得到其余的数据(未显示),然后生成QStandardItems的一个元组的新项,然后将其添加到“接收者列表”中,然后更新“接收者列表”的字典。

我相信有更好的方法来执行它。但由于我的初学者水平,我不能应用它。我将在最近的将来添加拖放选项,我认为可能有一种通过双击和将‘n’方法从一个列表拖到另一个列表来添加项目的共享(常见)方法。

我要求改进,优化和评论。

代码语言:javascript
复制
#!/usr/bin/env python -tt
# -*- coding: utf-8 -*-
#from PySide.QtGui import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *

import sys
reload(sys)
sys.setdefaultencoding('utf8')

data_for_tree = {"tomato":{"color":"red","ammount":"10", "note":"a note for tomato","price":"0.8"},"banana":{"color":"yellow","ammount":"1", "note":"b note for banana", "price":".6"}, "some fruit":{"color":"unknown","ammount":"100", "note":"some text","price":"2.1"}}
data_for_receiver = {"1":{"name":"milk","price":"3.2","note":"I love milk"}, "2":{"name":"coca-cola","price":".8","note":"coke forever"}}

class ProxyModel(QSortFilterProxyModel):

    def __init__(self, parent=None):
        super(ProxyModel, self).__init__(parent)

    def lessThan(self, left, right):
        leftData = self.sourceModel().data(left)
        rightData = self.sourceModel().data(right)
        try:
           return float(leftData) < float(rightData)
        except ValueError:
            return leftData < rightData

class MainFrame(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        self.MyTreeView = QTreeView()
        self.MyTreeViewModel = QStandardItemModel()
        self.MyTreeView.setModel(self.MyTreeViewModel)
        self.most_used_cat_header = ['Name', "ammount", "color"]
        self.MyTreeViewModel.setHorizontalHeaderLabels(self.most_used_cat_header)
        self.MyTreeView.setSortingEnabled(True)

        self.MyTreeView_Fill()

        self.receiver_tree = QTreeView()
        self.receiver_model = QStandardItemModel()
        self.receiver_tree.setModel(self.receiver_model)
        self.receiver_tree_header = ['#','Name', "price"]
        self.receiver_model.setHorizontalHeaderLabels(self.receiver_tree_header)


        self.MyTreeView.doubleClicked.connect(self.addToReceiver)

        self.receiver_fill()

        MainWindow = QHBoxLayout(self)    
        MainWindow.addWidget(self.MyTreeView)
        MainWindow.addWidget(self.receiver_tree)
        self.setLayout(MainWindow)

    def addToReceiver(self):
        indexes = self.MyTreeView.selectedIndexes()
        index_list =[i.data() for i in self.MyTreeView.selectedIndexes()]
        last_id = max(int(i) for i in data_for_receiver)
        for k in data_for_tree:
            v = data_for_tree[k]
            if [k,v["ammount"],v["color"]] == index_list:
                i =QStandardItem(str(last_id+1))
                name = QStandardItem(k)
                price = QStandardItem(format(float(v["price"]), ".2f"))
                tooltip = v["note"]
                name.setToolTip(tooltip)
                item = ( i, name, price)
                self.receiver_model.appendRow(item)
                upd  = {"name":k,"price":v["price"],"note":v["note"]}
                data_for_receiver[str(last_id+1)] = upd

    def MyTreeView_Fill(self):
        for k in data_for_tree:
            name = QStandardItem(k)
            ammount = QStandardItem(data_for_tree[k]["ammount"])
            note = QStandardItem(data_for_tree[k]["color"])
            name.setEditable(False)
            tooltip = "price "+format(float(data_for_tree[k]["price"]), ".2f")+"<br>"
            tooltip += data_for_tree[k]["note"]
            item = (name, ammount, note)
            name.setToolTip(tooltip)

            self.MyTreeViewModel.appendRow(item)
        self.MyTreeView.sortByColumn(1, Qt.DescendingOrder)
        proxyModel = ProxyModel(self)
        proxyModel.setSourceModel(self.MyTreeViewModel)
        self.MyTreeView.setModel(proxyModel)

        c = 0
        while c < len(self.most_used_cat_header):
            self.MyTreeView.resizeColumnToContents(c)
            c=c+1

    def receiver_fill(self):
        for k in data_for_receiver:
            v = data_for_receiver[k]
            i = QStandardItem(k)
            name = QStandardItem(v["name"])
            price = QStandardItem(format(float(v["price"]), ".2f"))
            tooltip = v["note"]
            name.setToolTip(tooltip)

            item = (i,name, price)
            self.receiver_model.appendRow(item)
        c = 0
        while c < len(self.receiver_tree_header):
            self.receiver_tree.resizeColumnToContents(c)
            c=c+1

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main = MainFrame()
    main.show()
    main.move(app.desktop().screen().rect().center() -     main.rect().center())
    sys.exit(app.exec_())
EN

回答 1

Code Review用户

发布于 2015-12-19 21:34:35

while循环适用于迭代未知次数(如while i == True: i = int(input("> ")) / 2 == 0 )。这将迭代,直到用户输入一个可被2整除的值。

for循环适用于在已知范围内进行迭代,例如for i in range(0, 10): print(i),它将打印0..9包含的数字。

在这里,您使用的是while循环,其中for循环更合适:

C=0,而c< len(self.most_used_cat_header):self.MyTreeView.resizeColumnToContents(c) c=c+1

这应该是:

代码语言:javascript
复制
for c in range(0, len(self.most_used_cat_header)):
    self.MyTreeView.resizeColumnToContents(c)

在上面的示例中,c不是一个信息特别丰富的名称。它代表什么,数组中的索引?您还使用其他未提供信息的名称,包括kvi等。名称长度不再受语言的限制,也不再影响运行时。

在这里,您可以在一行中为变量分配两个语句:

工具提示=“价格"+format(float(data_for_treeK),”.2f)+“ ”工具提示+= data_for_treeK

为什么不把这些加入到一个声明中呢?因为Python的字符串不可变,所以您首先要从添加到彼此的多个字符串中创建一个字符串,然后再创建另一个字符串。这里的性能成本没什么好担心的,但这是您在大量变异字符串时应该考虑的一个问题。

在大多数情况下,您的操作符间距看起来不错,但有时您会做'=‘(缺少第一个空格)或’=‘(开头的两个空格),而不是=。一致的代码更容易阅读,尽管这一点并不坏。

票数 5
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/92580

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档