52355

Dynamic QCombobox fill within Qtablewidget sourced from SQLite3 DB

Question:

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:

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

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

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.

There is a post similar to this one in some parts and might be found here: <a href="https://stackoverflow.com/questions/46689684/dynamic-qcombobox-fill-dependent-on-user-input-pyqt5/46691986?noredirect=1#comment80357051_46691986" rel="nofollow">Dynamic QComboBox fill dependent on user input PyQt5</a>.

During my research I found some other useful posts: <a href="https://stackoverflow.com/questions/30017853/sqlite3-table-into-qtablewidget-sqlite3-pyqt5" rel="nofollow">sqlite3 table into QTableWidget, sqlite3, PyQt5</a>, 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.

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

Answer1:

Here is the code I was after:

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

Recommend

  • JavaScript algorithm to give every possible combination of items and store them in an array [duplica
  • Why is this code not working? Hangman
  • Add a TCombobox Column to a Firemonkey TGrid
  • JQuery UI selectable plugin - Multiple mouse drag selection and unselect option
  • Combine two small queries (that group by different values) into one query
  • Set comboBox to custom display format
  • Watir::Exception::MissingWayOfFindingObjectException: invalid attribute: :css
  • Single virtual attribute definition for multiple fields
  • Symfony2.1 form date field: Argument 1 passed to … must be an instance of DateTime
  • Django: ORDER BY DESC on FloatField puts null values top?
  • Can't access Tomcat 7 Manager app when running from Eclipse
  • setContentView() is not enough to switch between layouts?
  • How do you remove the JComboBox 'click and see dropdown' functionality?
  • Why does the following throw an “Object doesn't support property or method 'importNode
  • Microsoft Excel Pivot miscalculation in Sum for positive and negative numbers
  • Flash radiobutton: how do I get the selected radiobutton?
  • Why must we declare a variable name when adding a method to a struct in Golang?
  • How can I restyle a word when rendering a pdf with pdf.js?
  • Suppressing passwd when calling sqlplus from shell script
  • RxJava debounce by arbitrary value
  • Conversion from string “a” to type 'Boolean' is not valid
  • How to revert to previous XCode version?
  • How can I set a binding to a Combox in a UserControl?
  • onBackPressed() not being executed
  • Rails Find when some params will be blank
  • Why is the size of this struct 32?
  • Deleting and Updating values from a cusrsor adapter
  • recyclerView does not call the onBindViewHolder when scroll in the view
  • Modifying destination and filename of gulp-svg-sprite
  • 'TypeError' while using NSGA2 to solve Multi-objective prob. from pyopt-sparse in OpenMDAO
  • ActionScript 2 vs ActionScript 3 performance
  • How to get next/previous record number?
  • Confusion with PayPal's monthly billing cycle
  • Data Validation Drop Down Box Arrow Disappearing
  • NSLayoutConstraint that would pin a view to the bottom edge of a superview
  • Why joiner is not used after Sequence generator or Update statergy
  • Authorize attributes not working in MVC 4
  • Busy indicator not showing up in wpf window [duplicate]
  • Python/Django TangoWithDjango Models and Databases
  • Net Present Value in Excel for Grouped Recurring CF