源自SQLite3 DB的Qtablewidget中的动态QCombobox填充

时间:2017-10-12 13:05:50

标签: python python-3.x sqlite pyqt5

我正在尝试将来自SQLite3数据库的动态Qcombobox(安排在Qtablewidget中)填充。基础数据(为了演示和简单起见)可以在由以下代码生成的表中找到:

import sqlite3

conn = sqlite3.connect('DataBase.db')
c = conn.cursor()

def create_table():
    c.execute('CREATE TABLE IF NOT EXISTS source("Section",\
                                                 "Product_ID",\
                                                 "Label",\
                                                 "Product_desc",\
                                                 "Unit_price")' )

list1 = [
    ['Butterfly','16/1/001','PP','Pepito Butterfly','350'],
    ['Butterfly','16/1/002','PP','Brown Butterfly','350'],
    ['Butterfly','16/1/003','PP','Blue Butterfly','350'],
    ['Butterfly','bra01','BR','White Butterfly','500'],
    ['Backpack','bra02','BR','Backpack-blue','1500'],
    ['Backpack','bra03','BR','Backpack-black','1250'],
    ['Toy','klv01','KL','Bear','200'],
    ['Toy','klv02','KL','Fish','500'],
    ['Toy','klv03','KL','Rabbit','400'],
    ['Toy','klv04','KL','Owl','450'],
    ]

def data_entry():
    for element in list1:
            c.execute("INSERT INTO source VALUES(?,?,?,?,?)", (element))
    conn.commit()
    c.close()
    conn.close()

create_table()
data_entry()

我的目标是更新所有组合框(在给定的行中),并在用户选择任何组合框中的任何内容时用更新的选择选项填充它们。逻辑应遵循:

Scenario1: 一个在combo1中选择Butterfly,combo2和combo3中的选择选项将更新如下:combo2显示三个选项(空白,PP,BR),默认设置为空白,combo3将显示(空白,Pepito Butterfly,Brown butterfly,Blue蝴蝶,白蝶)默认设置为空白,当用户在combo2中选择BR后,combo3的选项将仅提供空白和白色Buttefly(默认设置为空白)。

Scenario2: 在combo3中选择Backpack-black,combo2的选择选项只是空白和BR(默认设置为空白),combo1的选择选项只是空白和背包(默认设置为空白)。

场景3: 与Scenario1相同但在第二个实例中(在combo1中选择Butterfly之后)用户在combo3中选择White butterfly,combo2应该只提供空白和BR(默认设置为空白)。

空白值应该用作重启,以便用户重置选择选项。

在某些部分有一篇与此相似的帖子,可在此处找到:Dynamic QComboBox fill dependent on user input PyQt5

在我的研究过程中,我发现了一些其他有用的帖子:sqlite3 table into QTableWidget, sqlite3, PyQt5但是,我仍然没有设法实现代码,以便它可以工作并决定直接使用sqlite3提取数据。

我在初始阶段陷入困境,我需要形成一个数据结构,在信号通过后将进行更新(即选择)。下面是使用Qcomboboxes的Qtablewidget的代码,但我未能恰当地提供源代码:

进一步编辑 - 它已接近完成,所提供的选择似乎没问题,但由于某种原因无法选择它们:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sqlite3
from pandas import DataFrame

conn = sqlite3.connect('DataBase.db')
c = conn.cursor()
c.execute('select Section, Label, Product_desc from source')
offer = c.fetchall()
c.close()
conn.close()

df = DataFrame(offer)
fin = {}
for i in df:
    fin[i] = df[i]
    fin[i] = df[i].drop_duplicates()
    fin[i] = list(fin[i])
    fin[i].insert(0,'')

class Window(QMainWindow):

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

    def Table_of_widgets(self):

        rowCount = 20
        columnCount = 9

        self.table = QTableWidget()
        self.table.setColumnCount(columnCount)
        self.table.setRowCount(rowCount)
        self.table.setHorizontalHeaderLabels(['Section', 'Label', 'Product description', 'Picture', 'Product ID', "Amount", "Unit price", "Store", "Total price"])
        self.table.verticalHeader().hide()

        for i in range(columnCount):
            self.table.horizontalHeader().setSectionResizeMode(i, QHeaderView.Stretch)

        self.table.showMaximized()

        self.offer1 = fin[0]
        self.offer2 = fin[1]
        self.offer3 = fin[2]

        for i in range(rowCount):
            comboA = QComboBox()
            comboB = QComboBox()
            comboC = QComboBox()
            comboA.addItems(self.offer1)
            comboB.addItems(self.offer2)
            comboC.addItems(self.offer3)
            self.table.setCellWidget(i, 0, comboA)
            self.table.setCellWidget(i, 1, comboB)
            self.table.setCellWidget(i, 2, comboC)
            comboA.currentTextChanged.connect(lambda text1, row=i: self.onComboACurrentTextChanged(text1, row))
            comboB.currentTextChanged.connect(lambda text2, row=i: self.onComboBCurrentTextChanged(text2, row))
            comboC.currentTextChanged.connect(lambda text3, row=i: self.onComboCCurrentTextChanged(text3, row))

    def updateCombox(self, combo1, combo2, combo3, item1, item2, item3):
        text1 = combo1.currentText()
        text2 = combo2.currentText()
        text3 = combo3.currentText()
        combo1.blockSignals(True)
        combo2.blockSignals(True)
        combo3.blockSignals(True)
        combo1.clear()
        combo2.clear()
        combo3.clear()

        if text1 == '': a = list(df[0].drop_duplicates())
        else: a = [text1]
        if text2 == '': b = list(df[1].drop_duplicates())
        else: b = [text2]
        if text3 == '': c = list(df[2].drop_duplicates())
        else: c = [text3]

        offer1 = list(df.loc[df[0].isin(a) & df[1].isin(b) & df[2].isin(c)][0].drop_duplicates())
        offer1.insert(0, ' ')
        offer2 = list(df.loc[df[0].isin(a) & df[1].isin(b) & df[2].isin(c)][1].drop_duplicates())
        offer2.insert(0, ' ')
        offer3 = list(df.loc[df[0].isin(a) & df[1].isin(b) & df[2].isin(c)][2].drop_duplicates())
        offer3.insert(0, ' ')

        combo3.addItems(offer3)
        combo3.setCurrentText(text3)

        combo2.addItems(offer2)
        combo2.setCurrentText(text2)

        combo1.addItems(offer1)
        combo1.setCurrentText(text1)

        combo1.blockSignals(False)
        combo2.blockSignals(False)
        combo3.blockSignals(False)

    def onComboACurrentTextChanged(self, text1, row): # Determines changes in given row iniciated by comboA
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        comboC = self.table.cellWidget(row, 2)
        self.updateCombox(comboA, comboB, comboC, self.offer1, self.offer2, self.offer3)

    def onComboBCurrentTextChanged(self, text2, row): # Determines changes in given row iniciated by comboB
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        comboC = self.table.cellWidget(row, 2)
        self.updateCombox(comboA, comboB, comboC, self.offer1, self.offer2, self.offer3)

    def onComboCCurrentTextChanged(self, text3, row): # Determines changes in given row iniciated by comboC
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        comboC = self.table.cellWidget(row, 2)
        self.updateCombox(comboA, comboB, comboC, self.offer1, self.offer2, self.offer3)

if __name__ == "__main__":

    app = QApplication(sys.argv)
    app.setApplicationName('MyWindow')
    main = Window()
    sys.exit(app.exec_())

我会感谢任何建议/解决方案/提示!感谢

1 个答案:

答案 0 :(得分:0)

以下是我追随的代码:

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtCore import *
from PyQt5.QtGui import *
import sqlite3
from pandas import DataFrame

conn = sqlite3.connect('DataBase.db')
c = conn.cursor()
c.execute('select Section, Label, Product_desc from source')
offer = c.fetchall()
c.close()
conn.close()

df = DataFrame(offer)
fin = {}
for i in df:
    fin[i] = df[i]
    fin[i] = df[i].drop_duplicates()
    fin[i] = list(fin[i])
    fin[i].insert(0,' ')

class Window(QMainWindow):

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

    def Table_of_widgets(self):

        rowCount = 20
        columnCount = 9

        self.table = QTableWidget()
        self.table.setColumnCount(columnCount)
        self.table.setRowCount(rowCount)
        self.table.setHorizontalHeaderLabels(['Section', 'Label', 'Product description', 'Picture', 'Product ID', "Amount", "Unit price", "Store", "Total price"])
        self.table.verticalHeader().hide()

        for i in range(columnCount):
            self.table.horizontalHeader().setSectionResizeMode(i, QHeaderView.Stretch)

        self.table.showMaximized()

        self.offer1 = fin[0]
        self.offer2 = fin[1]
        self.offer3 = fin[2]

        for i in range(rowCount):
            comboA = QComboBox()
            comboB = QComboBox()
            comboC = QComboBox()
            comboA.addItems(self.offer1)
            comboB.addItems(self.offer2)
            comboC.addItems(self.offer3)
            self.table.setCellWidget(i, 0, comboA)
            self.table.setCellWidget(i, 1, comboB)
            self.table.setCellWidget(i, 2, comboC)
            comboA.currentTextChanged.connect(lambda text, row=i: self.onComboACurrentTextChanged(text, row))
            comboB.currentTextChanged.connect(lambda text, row=i: self.onComboBCurrentTextChanged(text, row))
            comboC.currentTextChanged.connect(lambda text, row=i: self.onComboCCurrentTextChanged(text, row))

    def updateCombox(self, combo1, combo2, combo3, offer1, offer2, offer3):
        text1 = combo1.currentText()
        text2 = combo2.currentText()
        text3 = combo3.currentText()
        combo1.blockSignals(True)
        combo2.blockSignals(True)
        combo3.blockSignals(True)
        combo1.clear()
        combo2.clear()
        combo3.clear()

        if text1 == ' ': a = list(df[0].drop_duplicates())
        else: a = [text1]
        if text2 == ' ': b = list(df[1].drop_duplicates())
        else: b = [text2]
        if text3 == ' ': c = list(df[2].drop_duplicates())
        else: c = [text3]

        offer1 = list(df.loc[df[0].isin(a) & df[1].isin(b) & df[2].isin(c)][0].drop_duplicates())
        offer1.insert(0, ' ')
        offer2 = list(df.loc[df[0].isin(a) & df[1].isin(b) & df[2].isin(c)][1].drop_duplicates())
        offer2.insert(0, ' ')
        offer3 = list(df.loc[df[0].isin(a) & df[1].isin(b) & df[2].isin(c)][2].drop_duplicates())
        offer3.insert(0, ' ')

        combo3.addItems(offer3)
        combo3.setCurrentText(text3)

        combo2.addItems(offer2)
        combo2.setCurrentText(text2)

        combo1.addItems(offer1)
        combo1.setCurrentText(text1)

        combo1.blockSignals(False)
        combo2.blockSignals(False)
        combo3.blockSignals(False)

    def onComboACurrentTextChanged(self, text, row):
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        comboC = self.table.cellWidget(row, 2)
        self.updateCombox(comboA, comboB, comboC, self.offer1, self.offer2, self.offer3)

    def onComboBCurrentTextChanged(self, text, row):
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        comboC = self.table.cellWidget(row, 2)
        self.updateCombox(comboA, comboB, comboC, self.offer1, self.offer2, self.offer3)

    def onComboCCurrentTextChanged(self, text, row):
        comboA = self.table.cellWidget(row, 0)
        comboB = self.table.cellWidget(row, 1)
        comboC = self.table.cellWidget(row, 2)
        self.updateCombox(comboA, comboB, comboC, self.offer1, self.offer2, self.offer3)

if __name__ == "__main__":

    app = QApplication(sys.argv)
    app.setApplicationName('MyWindow')
    main = Window()
    sys.exit(app.exec_())