来自 SQLite3 DB 的 Qtablewidget 中的动态 QCombobox 填充 [英] Dynamic QCombobox fill within Qtablewidget sourced from SQLite3 DB

查看:64
本文介绍了来自 SQLite3 DB 的 Qtablewidget 中的动态 QCombobox 填充的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to make a dynamic Qcombobox (arranged within Qtablewidget) fill sourced from SQLite3 database. The underlying data (for demonstration and simplicity sake) might be found within the table produced by following code:

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()

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

My aim is to update all comboboxes (in a given row) and fill them with updated selection options whenever the user selects something in any combobox. The logic should be following:

场景1:选择combo1中的Butterfly,combo2和combo3中的选项更新如下:combo2显示三个选项(blank,PP,BR),默认设置为blank,combo3会显示(blank,Pepito Butterfly,Brown butterfly,BlueButterfly, White Butterfly) 并且默认设置为空白,当用户在combo2 中选择BR 时,combo3 的选择选项将只提供空白和白色蝴蝶(默认设置为空白).

Scenario1: one chooses Butterfly within combo1, selection options within combo2 and combo3 will be updated as follows: combo2 displays three options (blank,PP,BR) and is set to blank by default, combo3 will display (blank,Pepito Butterfly,Brown butterfly,Blue Butterfly, White Butterfly) and is set to blank by default, when afterwards user selects BR within combo2 the selection options of combo3 will offer only blank and White Buttefly (set to blank by default).

场景2:在combo3中选择Backpack-black,combo2的选择选项只有空白和BR(默认设置为空白),combo1的选择选项将只有空白和Backpack(默认设置为空白).

Scenario2: one chooses Backpack-black in combo3, the selection options for combo2 will be just blank and BR (set to blank by default), the selection options for combo1 will be just blank and Backpack (set to blank by default).

场景3:与 Scenario1 相同,但在第二个实例中(在组合 1 中选择蝴蝶后)用户在组合 3 中选择白色蝴蝶,组合 2 应仅提供空白和 BR(默认设置为空白).

Scenario3: The same as Scenario1 but in second instance (after selecting Butterfly in combo1) user selects White butterfly in combo3 and combo2 should only offer blank and BR (set to blank by default).

空白值应作为重新启动以允许用户重置选择选项.

The blank values should serve as restart to enable user reset the selection options.

在某些部分有一篇与此类似的帖子,可以在这里找到:动态 QComboBox 填充取决于用户输入 PyQt5.

There is a post similar to this one in some parts and might be found here: Dynamic QComboBox fill dependent on user input PyQt5.

在我的研究中,我发现了一些其他有用的帖子:sqlite3 table into QTableWidget, sqlite3,PyQt5,然而,我仍然没有设法实现代码位,使其工作并决定直接使用 sqlite3 提取数据.

During my research I found some other useful posts: sqlite3 table into QTableWidget, sqlite3, PyQt5, however, I still did not manage to implement the bits of code so that it worked and decided to extract the data directly with sqlite3.

我在初始阶段陷入困境,需要形成一个数据结构,该结构将在信号传递(即进行选择)后更新.以下是带有 Qcomboboxes 的 Qtablewidget 代码,我未能正确获取:

I got stuck in initial phase at point where I need to form a structure of data that will be updated after signal is passed (i.e. selection is made). Here below is the code of Qtablewidget with Qcomboboxes I failed to source appropriately:

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

Further edit - it is nearly done, the offered selections seem to be alright but one cannot choose them for some reason:

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_())

对于任何建议/解决方案/提示,我将不胜感激!谢谢

I will be thankful for any suggestions/solutions/tips! Thanks

推荐答案

这是我想要的代码:

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_())

这篇关于来自 SQLite3 DB 的 Qtablewidget 中的动态 QCombobox 填充的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆