1

This program i already posted i don't want to repeat the duplicate question but in this i added widget to child widget, before my all functionalities are working good,When i add the widget i faced some problem in this program i tried in different ways.But still i have the same problem.In child widget i added line edits i want to change the one line edit text then automatically it will change last item line edit text.And search functionality also not working now.Please can any one help me how to solve this program

Given below is my code:

from PyQt4 import QtCore, QtGui
from functools import partial
global qty
class InventoryDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        super(InventoryDelegate, self).paint(painter, option, index)
        if not index.parent().isValid():
            painter.save()
            painter.setPen(QtGui.QPen(QtGui.QColor("white")))
            r = QtCore.QRect(option.rect)
            r.adjust(0, 1, 0, -1)
            painter.drawLine(r.topLeft(), r.topRight())
            painter.drawLine(r.bottomLeft(), r.bottomRight())
            painter.restore()

    def sizeHint(self, option, index):
        s = super(InventoryDelegate, self).sizeHint(option, index)
        s.setHeight(55)
        return s

class Inventory_Items(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Inventory_Items, self).__init__(parent)
        inv_obj =[{u'productPrice': 123.0, u'productSerialId': u'123458', u'productName': u'Renewal Application Form', u'productDiscount': 0, u'productdp': u'/media/ecommerce/pictureUploads/1546958016_35_admin_index.jpeg', u'productUnit': u'Quantity', u'data': [{u'product': 1837, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123457', u'product__howMuch': 2.0, u'productVariant__serialId': None, u'product__price': 123.0, u'pk': 65, u'productVariant__sku': None, u'quantity': -11.0}, {u'product': 1837, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123458', u'product__howMuch': 2.0, u'productVariant__serialId': None, u'product__price': 123.0, u'pk': 67, u'productVariant__sku': None, u'quantity': 10.0}, {u'product': 1837, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123459', u'product__howMuch': 2.0, u'productVariant__serialId': None, u'product__price': 123.0, u'pk': 69, u'productVariant__sku': None, u'quantity': 30.0}], u'productPk': 1837}, {u'productPrice': 1760.0, u'productSerialId': u'1168', u'productName': u'Truth or Delusion', u'productDiscount': 5, u'productdp': u'/media/ecommerce/pictureUploads/1546959987_35_admin_default.png', u'productUnit': u'Kilogram', u'data': [{u'product': 2180, u'product__unit': u'Kilogram', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'IND-BOK-D-2016-TRUDEL-02', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 1760.0, u'pk': 70, u'productVariant__sku': None, u'quantity': 10.0}, {u'product': 2180, u'product__unit': u'Kilogram', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'IND-BOK-D-2016-TRUDEL-01', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 1760.0, u'pk': 71, u'productVariant__sku': None, u'quantity': 1.0}], u'productPk': 2180}, {u'productPrice': 240.0, u'productSerialId': u'1219', u'productName': u'One-to-One Follow Up Slips ( Qty 10 pads - 50 sheets per pad)', u'productDiscount': 0, u'productdp': u'/media/ecommerce/pictureUploads/https%3A//bnistore.in/wp-content/uploads/2016/02/323.jpg', u'productUnit': u'Quantity', u'data': [{u'product': 2185, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123457', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 240.0, u'pk': 62, u'productVariant__sku': None, u'quantity': -48.0}], u'productPk': 2185}, {u'productPrice': 1500.0, u'productSerialId': u'3293', u'productName': u'Membership Application Form (Package of 10)', u'productDiscount': 0, u'productdp': u'/media/ecommerce/pictureUploads/https%3A//bnistore.in/wp-content/uploads/2017/08/New-Members-Application-Form.png', u'productUnit': u'quantity', u'data': [{u'product': 2225, u'product__unit': u'quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'IND-PRT-D-2016-NEWAPP-1', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 1500.0, u'pk': 66, u'productVariant__sku': None, u'quantity': 81.0}], u'productPk': 2225}]
        w = QtGui.QWidget()
        vbox = QtGui.QVBoxLayout(w)
        hbox = QtGui.QHBoxLayout()
        self.le = QtGui.QLineEdit()
        search = QtGui.QPushButton("search")
        search.clicked.connect(self.search_item)
        hbox.addWidget(self.le)
        hbox.addWidget(search)
        vbox.addLayout(hbox)
        self.inventory_widget = QtGui.QTreeWidget(columnCount=7,
            expandsOnDoubleClick=False,
            indentation=0,
            focusPolicy=QtCore.Qt.NoFocus,
            iconSize=QtCore.QSize(40,60))
        vbox.addWidget(self.inventory_widget)
        self.inventory_widget.setColumnWidth(2, 350)
        self.inventory_widget.setStyleSheet("QWidget {background-color: black;color: white;}")
        header = self.inventory_widget.header()
        header.hide()
        header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(2, QtGui.QHeaderView.Stretch)
        header.setResizeMode(3, QtGui.QHeaderView.Stretch)
        header.setResizeMode(4, QtGui.QHeaderView.Stretch)
        header.setResizeMode(5, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(6, QtGui.QHeaderView.ResizeToContents)

        delegate = InventoryDelegate(self.inventory_widget)
        self.inventory_widget.setItemDelegate(delegate)
        c=[]
        for obj in inv_obj:
            it = QtGui.QTreeWidgetItem()
            self.inventory_widget.addTopLevelItem(it)
            values = [
                obj["productName"],
                "Unit :  {0} ".format(obj["productUnit"]),
                "Price : {0} ".format(obj["productPrice"]),
                "Discount : {0} ".format(obj["productDiscount"])
            ]
            for i, t in enumerate(values):
                it.setText(i + 1, t)

            for v in obj['data']:
                child_it = QtGui.QTreeWidgetItem()
                it.addChild(child_it)
                value = [
                    v['product__serialNo'],
                    "{}".format(v['product__howMuch']),
                    "{}".format(v['quantity']),
                ]
                for l, m in enumerate(value):
                    child_it.setText(l + 1, m)

                    widget = QtGui.QWidget(self) # here i am adding new widget to child widget 
                    button_save = QtGui.QPushButton("save")
                    button_save.clicked.connect(self.save_qty)
                    self.le= QtGui.QLineEdit()
                    self.le.setFocus()
                    self.le.textChanged.connect(self.doSomething)
                    self.le.setText(m)
                    text = self.le.text()
                    button_save.setStyleSheet("background-color: blue;color: white;")
                    button_delete = QtGui.QPushButton("delete")
                    button_delete.setStyleSheet("background-color: red;color: white;")
                    lay = QtGui.QHBoxLayout(widget)
                    lay.addWidget(self.le)
                    lay.addStretch()
                    lay.addWidget(button_save)
                    lay.addWidget(button_delete)

                    self.inventory_widget.setItemWidget(child_it, 3, widget)
        self.inventory_widget.expandAll()
        self.setCentralWidget(w)

    def search_item(self):
        filter_text = self.le.text()
        is_valid_filter = filter_text == ""
        for i in range(self.inventory_widget.topLevelItemCount()):
            top_item = self.inventory_widget.topLevelItem(i)
            flag = (str(filter_text).lower() in str(top_item.text(1)).lower())  or is_valid_filter
            top_item.setHidden(not flag) #before its working good but after added widget to child widget search functionality is not working
    def doSomething(self,text):
        global qty
        print text,"TEXTTT"
        qty = text

    def save_qty(self):
        global qty
        print qty,"qtyyy"
        self.le.setText(qty) #here i click save buttons one more line edit text also changing...


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    settingobj= Inventory_Items()
    settingobj.showFullScreen()

    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
gowthami
  • 239
  • 2
  • 13
  • Could you explain what you want to do in save_qty and doSomething? – eyllanesc Feb 28 '19 at 18:01
  • actually sir when i run this program my line edits have default values after i want to update the text and that updated text i want to save in save_qt program. In do something function i am updating the value – gowthami Feb 28 '19 at 18:04

1 Answers1

3

The problem is that you are overwriting a variable several times, for example in the beginning self.le refers to the QLineEdit that performs the filtering, but then self.le will be the widget set in the QTreeWidget so in general the self.le no longer is the initial QLineEdit so the filter fails.

One solution is to create a custom widget that handles that information and exposes the clicked signal and text, in the slot you get the widget using the sender method:

Finally avoid using global variables, for more reference read Why are global variables evil?.

from PyQt4 import QtCore, QtGui

class InventoryDelegate(QtGui.QStyledItemDelegate):
    def paint(self, painter, option, index):
        super(InventoryDelegate, self).paint(painter, option, index)
        if not index.parent().isValid():
            painter.save()
            painter.setPen(QtGui.QPen(QtGui.QColor("white")))
            r = QtCore.QRect(option.rect)
            r.adjust(0, 1, 0, -1)
            painter.drawLine(r.topLeft(), r.topRight())
            painter.drawLine(r.bottomLeft(), r.bottomRight())
            painter.restore()

    def sizeHint(self, option, index):
        s = super(InventoryDelegate, self).sizeHint(option, index)
        s.setHeight(55)
        return s

class Widget(QtGui.QWidget):
    saveClicked = QtCore.pyqtSignal()
    deleteClicked = QtCore.pyqtSignal()

    def __init__(self, text, parent=None):
        super(Widget, self).__init__(parent)
        self.le= QtGui.QLineEdit(text=text)
        button_save = QtGui.QPushButton(text="save", clicked=self.saveClicked)
        button_save.setStyleSheet("background-color: blue;color: white;")
        button_delete = QtGui.QPushButton(text="delete", clicked=self.deleteClicked)
        button_delete.setStyleSheet("background-color: red;color: white;")
        lay = QtGui.QHBoxLayout(self)
        lay.addWidget(self.le)
        lay.addStretch()
        lay.addWidget(button_save)
        lay.addWidget(button_delete)

    def text(self):
        return self.le.text()

class Inventory_Items(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(Inventory_Items, self).__init__(parent)
        inv_obj =[{u'productPrice': 123.0, u'productSerialId': u'123458', u'productName': u'Renewal Application Form', u'productDiscount': 0, u'productdp': u'/media/ecommerce/pictureUploads/1546958016_35_admin_index.jpeg', u'productUnit': u'Quantity', u'data': [{u'product': 1837, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123457', u'product__howMuch': 2.0, u'productVariant__serialId': None, u'product__price': 123.0, u'pk': 65, u'productVariant__sku': None, u'quantity': -11.0}, {u'product': 1837, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123458', u'product__howMuch': 2.0, u'productVariant__serialId': None, u'product__price': 123.0, u'pk': 67, u'productVariant__sku': None, u'quantity': 10.0}, {u'product': 1837, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123459', u'product__howMuch': 2.0, u'productVariant__serialId': None, u'product__price': 123.0, u'pk': 69, u'productVariant__sku': None, u'quantity': 30.0}], u'productPk': 1837}, {u'productPrice': 1760.0, u'productSerialId': u'1168', u'productName': u'Truth or Delusion', u'productDiscount': 5, u'productdp': u'/media/ecommerce/pictureUploads/1546959987_35_admin_default.png', u'productUnit': u'Kilogram', u'data': [{u'product': 2180, u'product__unit': u'Kilogram', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'IND-BOK-D-2016-TRUDEL-02', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 1760.0, u'pk': 70, u'productVariant__sku': None, u'quantity': 10.0}, {u'product': 2180, u'product__unit': u'Kilogram', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'IND-BOK-D-2016-TRUDEL-01', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 1760.0, u'pk': 71, u'productVariant__sku': None, u'quantity': 1.0}], u'productPk': 2180}, {u'productPrice': 240.0, u'productSerialId': u'1219', u'productName': u'One-to-One Follow Up Slips ( Qty 10 pads - 50 sheets per pad)', u'productDiscount': 0, u'productdp': u'/media/ecommerce/pictureUploads/https%3A//bnistore.in/wp-content/uploads/2016/02/323.jpg', u'productUnit': u'Quantity', u'data': [{u'product': 2185, u'product__unit': u'Quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'123457', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 240.0, u'pk': 62, u'productVariant__sku': None, u'quantity': -48.0}], u'productPk': 2185}, {u'productPrice': 1500.0, u'productSerialId': u'3293', u'productName': u'Membership Application Form (Package of 10)', u'productDiscount': 0, u'productdp': u'/media/ecommerce/pictureUploads/https%3A//bnistore.in/wp-content/uploads/2017/08/New-Members-Application-Form.png', u'productUnit': u'quantity', u'data': [{u'product': 2225, u'product__unit': u'quantity', u'productVariant__unitPerpack': None, u'productVariant': None, u'productVariant__price': None, u'product__serialNo': u'IND-PRT-D-2016-NEWAPP-1', u'product__howMuch': 1.0, u'productVariant__serialId': None, u'product__price': 1500.0, u'pk': 66, u'productVariant__sku': None, u'quantity': 81.0}], u'productPk': 2225}]
        w = QtGui.QWidget()
        vbox = QtGui.QVBoxLayout(w)
        hbox = QtGui.QHBoxLayout()
        self.le = QtGui.QLineEdit()
        search = QtGui.QPushButton("search")
        search.clicked.connect(self.search_item)
        hbox.addWidget(self.le)
        hbox.addWidget(search)
        vbox.addLayout(hbox)
        self.inventory_widget = QtGui.QTreeWidget(columnCount=7,
            expandsOnDoubleClick=False,
            indentation=0,
            focusPolicy=QtCore.Qt.NoFocus,
            iconSize=QtCore.QSize(40,60))
        vbox.addWidget(self.inventory_widget)
        self.inventory_widget.setColumnWidth(2, 350)
        self.inventory_widget.setStyleSheet("QWidget {background-color: black;color: white;}")
        header = self.inventory_widget.header()
        header.hide()
        header.setResizeMode(0, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(1, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(2, QtGui.QHeaderView.Stretch)
        header.setResizeMode(3, QtGui.QHeaderView.Stretch)
        header.setResizeMode(4, QtGui.QHeaderView.Stretch)
        header.setResizeMode(5, QtGui.QHeaderView.ResizeToContents)
        header.setResizeMode(6, QtGui.QHeaderView.ResizeToContents)

        delegate = InventoryDelegate(self.inventory_widget)
        self.inventory_widget.setItemDelegate(delegate)
        c=[]
        for obj in inv_obj:
            it = QtGui.QTreeWidgetItem()
            self.inventory_widget.addTopLevelItem(it)
            values = [
                obj["productName"],
                "Unit :  {0} ".format(obj["productUnit"]),
                "Price : {0} ".format(obj["productPrice"]),
                "Discount : {0} ".format(obj["productDiscount"])
            ]
            for i, t in enumerate(values):
                it.setText(i + 1, t)

            for v in obj['data']:
                child_it = QtGui.QTreeWidgetItem()
                it.addChild(child_it)
                value = [
                    v['product__serialNo'],
                    "{}".format(v['product__howMuch']),
                    "{}".format(v['quantity']),
                ]
                for l, m in enumerate(value):
                    child_it.setText(l + 1, m)
                    widget = Widget(m)
                    widget.saveClicked.connect(self.save_qty)
                    self.inventory_widget.setItemWidget(child_it, 3, widget)
        self.inventory_widget.expandAll()
        self.setCentralWidget(w)

    @QtCore.pyqtSlot()
    def search_item(self):
        filter_text = self.le.text()
        is_valid_filter = filter_text == ""
        for i in range(self.inventory_widget.topLevelItemCount()):
            top_item = self.inventory_widget.topLevelItem(i)
            flag = (str(filter_text).lower() in str(top_item.text(1)).lower())  or is_valid_filter
            top_item.setHidden(not flag)

    @QtCore.pyqtSlot()
    def save_qty(self):
        widget = self.sender()
        print(widget.text())


if __name__ == '__main__':
    import sys
    app = QtGui.QApplication(sys.argv)
    settingobj= Inventory_Items()
    settingobj.showFullScreen()

    sys.exit(app.exec_())
eyllanesc
  • 235,170
  • 19
  • 170
  • 241
  • sir after i added the widget my search function also not working – gowthami Feb 28 '19 at 18:24
  • i want to search with item_name sir – gowthami Feb 28 '19 at 18:28
  • sir i don't have laptop right now, if you don't mine i will check if any issue is there i will update my code on tomorrow – gowthami Feb 28 '19 at 18:36
  • Once again Thank you so much sir – gowthami Feb 28 '19 at 18:36
  • i didn't mean that way sir just i am asking – gowthami Feb 28 '19 at 18:41
  • @gowthami I understand that from the beginning since you clearly indicate it in your question, and in the first paragraph of my answer I indicate the reason for that problem. Not only you must use my code my solution but also you must read my explanation :-), let me know if my solution has problems – eyllanesc Feb 28 '19 at 18:44
  • Thank you so much..I am in beginner stage in pyqt4. Daily i followed your updated answers in stack overflow really those are very helpful to me,i learned so many things from your answers..No words you are my favourite professor... – gowthami Mar 01 '19 at 04:00