QTablewidget doesn't show new cellWidgets in PyQt5 - python

My Program is written in Python3.5 and PyQt5. I have a method in my class that adds some custom widgets to a QTableWidget. when I call the function from inside the class it works and changes the cellwidgets of QTablewidget but when I call it from another custom class it doesn't change the widgets. I checked and the items and indexes changes but the new cellwidgets doesn't show. what is the problem?
This is my code:
class mainmenupage(QWidget):
elist = []
def __init__(self):
#the main window widget features
self.setObjectName("mainpage")
self.resize(800, 480)
sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.sizePolicy().hasHeightForWidth())
self.setSizePolicy(sizePolicy)
self.setMinimumSize(QSize(800, 480))
self.setMaximumSize(QSize(800, 480))
#the QTreeWidget features
self.category_tree = QTreeWidget(self)
self.category_tree.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.category_tree.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.category_tree.setGeometry(QRect(630, 90, 161, 381))
self.category_tree.setLayoutDirection(Qt.RightToLeft)
self.category_tree.setLocale(QLocale(QLocale.Persian, QLocale.Iran))
self.category_tree.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.category_tree.setUniformRowHeights(False)
self.category_tree.setColumnCount(1)
self.category_tree.setObjectName("category_tree")
self.category_tree.headerItem().setText(0, "1")
self.category_tree.setFrameShape(QFrame.NoFrame)
self.category_tree.header().setVisible(False)
self.category_tree.header().setSortIndicatorShown(False)
self.category_tree.setFocusPolicy(Qt.NoFocus))
#the QTableWidget features. It comes from the custom class myTableWidget
self.main_table = myTableWidget(self)
self.main_table.setGeometry(QRect(20, 140, 600, 330))
sizePolicy = QSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(0)
sizePolicy.setHeightForWidth(self.main_table.sizePolicy().hasHeightForWidth())
self.main_table.setSizePolicy(sizePolicy)
self.main_table.setMinimumSize(QSize(0, 0))
self.main_table.setLayoutDirection(Qt.LeftToRight)
self.main_table.setLocale(QLocale(QLocale.Persian, QLocale.Iran))
self.main_table.setInputMethodHints(Qt.ImhNone)
self.main_table.setFrameShape(QFrame.NoFrame)
self.main_table.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.main_table.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
self.main_table.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.main_table.setTabKeyNavigation(False)
self.main_table.setShowGrid(False)
self.main_table.setCornerButtonEnabled(False)
self.main_table.setUpdatesEnabled(True)
self.main_table.setRowCount(2)
self.main_table.setColumnCount(2)
self.main_table.setObjectName("main_table")
self.main_table.horizontalHeader().setVisible(False)
self.main_table.horizontalHeader().setHighlightSections(False)
self.main_table.verticalHeader().setVisible(False)
self.main_table.verticalHeader().setHighlightSections(False)
self.main_table.setFocusPolicy(Qt.NoFocus)
self.main_table.setSelectionMode(QAbstractItemView.NoSelection)
self.main_table.horizontalHeader().setDefaultSectionSize(300)
self.main_table.verticalHeader().setDefaultSectionSize(165)
self.category_tree.itemPressed.connect(self.insertdata)
def insertdata(self,subcat):
#get the text of clicked item from qtreewidget
item = self.category_tree.currentItem().text(0)
#get data from DB
datas = self.conn.retrievedata('*','words',"subcat='{}'".format(item))
#check if the list of copied data is empty or not
if mainmenupage.elist != []:
del mainmenupage.elist[:]
#if the list is empty, the data received from DB appends to it
if mainmenupage.elist == []:
for data in datas:
mainmenupage.elist.append(data)
#delete the first index of copied list because it isn't needed here
mainmenupage.elist = mainmenupage.elist[1:]
# calls the populatemain function for populating qtablewidget with these datas with a custom index e.g. index 5 to 9.
self.populatemain(5,9)
def populatemain(self,startindexdata,endindexdata):
#make a list for indexes of items that will be added to qtablewidget
mtl=[]
for i in range(2):
for j in range(2):
mtl.append(i)
mtl.append(j)
#adding custom widgets as cellWidgets to qtablewidget
for index, my in enumerate(zip(*[iter(mtl)]*2)):
if mainmenupage.elist != []:
data = mainmenupage.elist[startindexdata:endindexdata][index]
exec("self.iteM{} = CustomWidget('{}','content/img/food.png')".format(data[0],data[4]))
exec("self.main_table.setCellWidget({} ,{}, self.iteM{})".format(*my,data[0]))
class myTableWidget(QTableWidget):
def checking(self):
if (self.endgingposx - self.startingposx) <= -50:
#a custom function for checking that if the user made a swipe to left on the qtablewidget for chaning it's content
if mainmenupage.elist != []:
#make an instance from the previous class for accessing to populatemain method
x = mainmenupage()
#calling populatemain method for changing widgets in qtablewidget with the items made from different indexes of the copied data list e.g. indexes 0 to 4. but i don't know why this doesn't change the items. The populatemain function runs correctly it can be checked by putting print statement in it but it doesn't change the Qtablewidget contents.
x.populatemain(0,4)
def mousePressEvent(self,event):
super().mousePressEvent(event)
self.startingposx = event.x()
def mouseReleaseEvent(self,event):
super().mouseReleaseEvent(event)
self.endgingposx = event.x()
self.checking()
class CustomWidget(QWidget):
def __init__(self, text, img, parent=None):
QWidget.__init__(self, parent)
self._text = text
self._img = img
self.setLayout(QVBoxLayout())
self.lbPixmap = QLabel(self)
self.lbText = QLabel(self)
self.lbText.setAlignment(Qt.AlignCenter)
self.layout().addWidget(self.lbPixmap)
self.layout().addWidget(self.lbText)
self.initUi()
def initUi(self):
self.lbPixmap.setPixmap(QPixmap(self._img).scaled(260,135,Qt.IgnoreAspectRatio,transformMode = Qt.SmoothTransformation))
self.lbText.setText(self._text)
#pyqtProperty(str)
def img(self):
return self._img
#img.setter
def total(self, value):
if self._img == value:
return
self._img = value
self.initUi()
#pyqtProperty(str)
def text(self):
return self._text
#text.setter
def text(self, value):
if self._text == value:
return
self._text = value
self.initUi()
self.category_tree is a QTreeWidget
self.main_table is a QTableWidget
For completing my question. When I click on one of the self.category_tree items it calls insertdata. At the last line of insertdata I call self.populatemain(5,9) it adds 4 custom widgets to my table, but when the checking method from myTableWidget class calls populatemain with other indexes the qtablewidget items doesn't change. What's wrong?
Thank you in advance.

After a lot of efforts finally I solved my problem this way:
I made a Qframe and putted the QTableWidget in it, and then I editted the mousePressEvent of the QTableWidget to call mousePressEvent of the QFrame that is below if this table, and then simply checked for starting and ending positions of clicking and made a function to update the QTableWidget's contents when swiping happens. I posted this to help anyone else that goes to problems like this.

Related

How can i align a CellWidget of a TableWidget to the center of the Item in pyqt5

i have a comboBox inside of a tableWidget and the verticalHeader DefaultSectionSize is 60.
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
QtWidgets.QMainWindow.__init__(self,parent)
self.table = QTableWidget()
self.setCentralWidget(self.table)
self.table.verticalHeader().setDefaultSectionSize(60)
self.table.setColumnCount(2)
self.table.setRowCount(2)
data = ["1","2"]
for i in range(2):
item = QTableWidgetItem(data[i])
self.table.setItem(i,0,item)
self.combo_sell = QComboBox()
self.combo_sell.setMaximumHeight(30)
self.table.setCellWidget(i,1,self.combo_sell)
But since i set the maximum size of the comboBox to 30, it stays in the top of the item.
I want to know if there's a way to align it to the center.
When setting an index widget, the view tries to set the widget geometry based on the visualRect() of the index. Setting a fixed dimension forces the widget to align itself to the default origin, which is usually the top left corner.
The only way to vertically center a widget with a fixed height is to use a container with a vertical box layout and add the combo to it:
for i in range(2):
item = QTableWidgetItem(data[i])
item.setTextAlignment(Qt.AlignCenter)
self.table.setItem(i,0,item)
container = QWidget()
layout = QVBoxLayout(container)
combo_sell = QComboBox()
layout.addWidget(combo_sell)
combo_sell.setMaximumHeight(30)
self.table.setCellWidget(i, 1, container)
Note: setting instance attributes in a for loop is pointless, as the reference is lost every time the cycle loops.
If you need a simple reference to the combo, you can set it as an attribute of the widget:
container.combo_sell = QComboBox()
In this way you can easily access it when required:
widget = self.table.cellWidget(row, column)
if widget and hasattr(widget, 'combo'):
combo = widget.combo
print(combo.currentIndex())
Note that the reference is created for the python wrapper of the widget, and that behavior might change in future versions of Qt. A better and safer way to achieve this would be to use a subclass, which would also allow easier access to the combo:
class TableCombo(QWidget):
def __init__(self):
super().__init__()
layout = QVBoxLayout(self)
self.combo = QComboBox()
layout.addWidget(self.combo)
self.combo.setMaximumHeight(30)
self.currentIndex = self.combo.currentIndex
self.setCurrentIndex = self.combo.setCurrentIndex
self.addItems = self.combo.addItems
# ...
combo_sell = TableCombo()
self.table.setCellWidget(i, 1, combo_sell)
# ...
combo = self.table.cellWidget(row, column)
print(combo.currentIndex())

Using QStyledItemDelegates as custom items in QListView

I want to design a custom ListView widget which has custom items similar to this:
https://i.stack.imgur.com/iTNbN.png
However, the qt documentation and some stackoverflow posts state that one should ideally use a QStyleItemDelegate. I never worked with 'delegates' before but as far as I understood from my research they are called by the ListView for drawing / rendering each item.
I found a delegate example in another project (https://github.com/pyblish/pyblish-lite/blob/master/pyblish_lite/delegate.py) and they draw everything by hand / are essentially rebuilding entire widgets by painting rectangles.
This seems a bit impractical for me as most of the time custom item widgets can be compounds of existing widgets. Take a look at the screenshot above. It essentially contains a Qlabel, QPixmap, and four DoubleSpinBoxes.
Question: How would you use the painting / rendering methods that already exist in them instead of manually painting everything on your own?
That way you can profit from existing member methods and can use layouts for structuring your widget.
For example the first ListViewItem should pass the model data to the delegate so that the text of the self.lightGroupName QLabel can be set to "Light1".
Any help is greatly appreciated, since I have no idea how to go on from here:
from PySide2 import QtCore, QtGui, QtWidgets
class LightDelagate(QtWidgets.QStyledItemDelegate): #custom item view
def __init__(self, parent=None):
super(LightDelagate, self).__init__(parent)
self.setupUI()
def setupUI(self):
self.masterWidget = QtWidgets.QWidget()
#Light Group Header
self.hlayLightHeader = QtWidgets.QHBoxLayout()
self.lightGroupName = QtWidgets.QLabel("Checker")
self.hlayLightHeader.addWidget(self.lightGroupName)
#Light AOV Preview
self.lightPreview = QtWidgets.QLabel()
#set size
self.aovThumbnail = QtGui.QPixmap(180, 101)
#self.lightPreview.setPixmap(self.aovThumbnail.scaled(self.lightPreview.width(), self.lightPreview.height(), QtCore.Qt.KeepAspectRatio))
# #Color Dials
# self.hlayColorDials = QtWidgets.QHBoxLayout()
# self.rgbDials = QtWidgets.QHBoxLayout()
# self.rDial = QtWidgets.QDoubleSpinBox()
# self.rDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
# self.gDial = QtWidgets.QDoubleSpinBox()
# self.gDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
# self.bDial = QtWidgets.QDoubleSpinBox()
# self.bDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
# self.rgbDials.addWidget(self.rDial)
# self.rgbDials.addWidget(self.gDial)
# self.rgbDials.addWidget(self.bDial)
# #Exposure
# self.hlayExposureDials = QtWidgets.QHBoxLayout()
# self.exposureDial = QtWidgets.QDoubleSpinBox()
# self.exposureDial.setButtonSymbols(QtWidgets.QAbstractSpinBox.NoButtons)
# self.hlayExposureDials.addWidget(self.exposureDial)
# self.hlayColorDials.addLayout(self.rgbDials)
# self.hlayColorDials.addLayout(self.hlayExposureDials)
#entire layout
self.vlayWidget = QtWidgets.QVBoxLayout()
self.vlayWidget.addLayout(self.hlayLightHeader)
self.vlayWidget.addWidget(self.lightPreview)
# self.vlayWidget.addLayout(self.hlayColorDials)
self.vlayWidget.setContentsMargins(2,2,2,2)
self.vlayWidget.setSpacing(2)
self.masterWidget.setLayout(self.vlayWidget)
def paint(self, painter, option, index):
rowData = index.model().data(index, QtCore.Qt.DisplayRole)
self.lightGroupName.setText(rowData[0])
print (option.rect)
painter.drawRect(option.rect)
painter.drawText()
def sizeHint(self, option, index):
return QtCore.QSize(200, 150)
class LightListModel(QtCore.QAbstractListModel): #data container for list view
def __init__(self, lightList= None):
super(LightListModel, self).__init__()
self.lightList = lightList or []
#reimplement
def rowCount(self, index):
return len(self.lightList)
def data(self, index, role):
if role == QtCore.Qt.DisplayRole:
lightGroupData = self.lightList[index.row()]
return lightGroupData
class LightListView(QtWidgets.QListView): #
def __init__(self):
super(LightListView, self).__init__()
self.setFlow(QtWidgets.QListView.LeftToRight)
self.setItemDelegate(LightDelagate(self))
self.setMinimumWidth(1880)
lightListTest = [
('Light1' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)}),
('Light2' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)}),
('Light3' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)}),
('Light4' , {'lightList' : [], 'lightColor': (0,0,0), 'mod_exposure': 1, 'mod_color' : (0,0,0)})
]
app = QtWidgets.QApplication([])
LLV = LightListView()
model = LightListModel(lightList=lightListTest)
LLV.setModel(model)
LLV.show()
LLV.setSe
app.exec_()
Instead of QListView, could you use QListWidget and override itemWidget? The idea would be that this lets you return a QWidget (with children as per your screenshot) instead of having to implement a QStyledItemDelegate that calls each child widget's paint method.

How to change icon of item by using QStyledItemDelegate for custom QItemlist depends on condition?

I build a QListwidget with custom itemwidget this list. The idea I want to change the icon of the item depends on condition. I read about the MVC model, but I couldn't know how to built QStyledItemDelegate to update them.
Now, I delete all items in the list and read them, that works if the list small but when I have a lot of item it takes time.
This code of CostmItemWidget:
class CustomQWidget(QWidget):
def __init__(self, file, parent=None):
super(CustomQWidget, self).__init__(parent)
if file["l_file"]:
pathname = os.path.join(parent.parent.main_script_path, "icons/correct.png")
else:
pathname = os.path.join(parent.parent.main_script_path, "icons/wrong.png")
pixmap = QtGui.QPixmap(pathname)
button = QPushButton()
button.setStyleSheet("padding: 0px;")
button.setFixedSize(16, 16)
# resize pixmap
pixmap = pixmap.scaled(button.size(), QtCore.Qt.KeepAspectRatioByExpanding, QtCore.Qt.SmoothTransformation)
cropOffsetX = (pixmap.width() - button.size().width()) / 2
pixmap = pixmap.copy(cropOffsetX, 0, button.size().width(), button.size().height())
button.setIcon(QtGui.QIcon(pixmap))
button.setIconSize(button.size())
button.setFlat(True)
label = QLabel(file["n_file"])
layout = QHBoxLayout()
layout.addWidget(button, 0)
layout.addWidget(label, 0)
layout.setContentsMargins(0, 0, 0, 0)
self.setLayout(layout)
And this code of widget content list:
class FileListWidget(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
loadUi(os.path.join(".", "UIFiles", 'filelist_widget.ui'), self)
self.parent = parent
self.refresh_list()
self.list_view.setCurrentRow(0)
self.list_view.itemClicked.connect(self.selected_file)
self.list_view.setStyleSheet("QListWidget::item { padding: 0px; }")
def refresh_list(self):
self.list_view.clear()
if len(self.parent.files) == 0:
return
for index, file in self.parent.files.iterrows():
self.add_item_list(file)
self.parent.image_deleted = False
def add_item_list(self, file):
item = QListWidgetItem(self.list_view)
item.setSizeHint(QSize(item.sizeHint().width(), 20))
item_widget2 = CustomQWidget(file, self)
self.list_view.addItem(item)
self.list_view.setItemWidget(item, item_widget2)
I looking to find a way of applying QStyledItemDelegate and change the icon by a certain signal. The icon of the button in the CustomQWidget and I want to change it when the value of "l_file" from the dictionary is True.
This image of the list I have
I created this delegate to handle put icon inside the custom Widget of the QListItemWidget.
class FileListDelegate(QStyledItemDelegate):
def __init__(self, parent, list_view):
super(FileListDelegate, self).__init__(parent)
# pointer to list
self.list_view = list_view
def paint(self, painter: QtGui.QPainter, option: QStyleOptionViewItem, index: QtCore.QModelIndex) -> None:
painter.save()
item = self.list_view.itemFromIndex(index)
widget = self.list_view.itemWidget(item)
layout = widget.layout()
button = layout.itemAt(0).widget()
if self.list_view.parent().parent().parent.files.loc[widget.index, 'l_file']:
pathname = os.path.join(widget.main_script_path, "icons/correct.png")
else:
pathname = os.path.join(widget.main_script_path, "icons/wrong.png")
pixmap = QtGui.QPixmap(pathname)
button.setIcon(QtGui.QIcon(pixmap))
button.setIconSize(button.size())
painter.restore()

Qcombobox with Qlabel and signal&slot

I have a Qgroupbox which contains Qcombobox with Qlabels, I want to select a value from Qcombobox and display the value as Qlabel. I have the complete code, even I do print value before and after within function every thing works as it should, Only display setText wont set text to Qlabel and update it.
Current screen
What I want
I've corrected signal code, when Qgroupbox in it Qcombobox appears or value would be changed, self.activation.connect(......) would emit an int of the index. to ensure that would work I print it-value inside the def setdatastrength(self, index), see figure below indeed it works, then argument would be passed to function self.concreteproperty.display_condata(it) would be called and do a print of value inside def display_condata(self, value) to make sure about value passing, as shown figure below, it does work. This line code self.con_strength_value.setText(fmt.format(L_Display))
wont assign value to Qlabel.
The script
import sys
from PyQt5 import QtCore, QtGui, QtWidgets
class secondtabmaterial(QtWidgets.QWidget):
def __init__(self, parent=None):
super(secondtabmaterial, self).__init__(parent)
self.concretewidgetinfo = ConcreteStrengthInFo()
Concrete_Group = QtWidgets.QGroupBox(self)
Concrete_Group.setTitle("&Concrete")
Concrete_Group.setLayout(self.concretewidgetinfo.grid)
class ConcreteStrengthComboBox(QtWidgets.QComboBox):
def __init__(self, parent = None):
super(ConcreteStrengthComboBox, self).__init__(parent)
self.addItems(["C12/15","C16/20","C20/25","C25/30","C30/37","C35/45"
,"C40/50","C45/55","C50/60","C55/67","C60/75","C70/85",
"C80/95","C90/105"])
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.compressive_strength = ["12","16","20","25","30","35","40",
"45","50","55","60","70","80","90"]
class ConcreteProperty(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ConcreteProperty, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
concretestrength_lay = QtWidgets.QHBoxLayout(self)
fctd = "\nfcd\n\nfctd\n\nEc"
con_strength = QtWidgets.QLabel(fctd)
self.con_strength_value = QtWidgets.QLabel(" ")
concretestrength_lay.addWidget(con_strength)
concretestrength_lay.addWidget(self.con_strength_value, alignment=QtCore.Qt.AlignRight)
self.setLayout(concretestrength_lay)
#QtCore.pyqtSlot(int)
def display_condata(self, value):
try:
L_Display = str(value)
print("-------- After ------")
print(L_Display, type(L_Display))
fmt = "{}mm"
self.con_strength_value.setText(fmt.format(L_Display))
except ValueError:
print("Error")
class ConcreteStrengthInFo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ConcreteStrengthInFo, self).__init__(parent)
self.concreteproperty = ConcreteProperty()
self.concretestrengthbox = ConcreteStrengthComboBox()
self.concretestrengthbox.activated.connect(self.setdatastrength)
hbox = QtWidgets.QHBoxLayout()
concrete_strength = QtWidgets.QLabel("Concrete strength: ")
hbox.addWidget(concrete_strength)
hbox.addWidget(self.concretestrengthbox)
self.grid = QtWidgets.QGridLayout()
self.grid.addLayout(hbox, 0, 0)
self.grid.addWidget(self.concreteproperty, 1, 0)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
it = self.concretestrengthbox.compressive_strength[index]
self.concreteproperty.display_condata(it)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
w = secondtabmaterial()
w.show()
sys.exit(app.exec_())
Above code is corrected and final. Now it works as it should.
I think the issue is that your receiving slot doesn't match any of the available .activated signals.
self.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot()
def setdatastrength(self):
index = self.currentIndex()
it = self.compressive_strength[index]
print(it)
self.concreteproperty.display_condata(it)
The QComboBox.activated signal emits either an int of the index, or a str of the selected value. See documentation.
You've attached it to setdatastrength which accepts doesn't accept any parameters (aside from self, from the object) — this means it doesn't match the signature of either available signal, and won't be called. If you update the definition to add the index value, and accept a single int it should work.
self.activated.connect(self.setdatastrength)
#QtCore.pyqtSlot(int) # add the target type for this slot.
def setdatastrength(self, index):
it = self.compressive_strength[index]
print(it)
self.concreteproperty.display_condata(it)
After the update — the above looks now to be fixed, although you don't need the additional index = self.currentIndex() in setdatastrength it's not doing any harm.
Looking at your code, I think the label is being updated. The issue actually is that you can't see the label at all. Looking at the init for ConcreteProperty
class ConcreteProperty(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ConcreteProperty, self).__init__(parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.concretestrength_lay = QtWidgets.QHBoxLayout()
fctd = "\nfcd\n\nfctd\n\nEc"
con_strength = QtWidgets.QLabel(fctd)
self.con_strength_value = QtWidgets.QLabel(" ")
self.concretestrength_lay.addWidget(con_strength)
self.concretestrength_lay.addWidget(self.con_strength_value, alignment=QtCore.Qt.AlignLeft)
The reason the changes are not appearing is that you create two ConcreteProperty objects, one in ConcreteStrengthInfo and one in ConcreteStrengthComboBox. Updates to the combo box trigger an update of the ConcreteProperty attached to the combobox, not the other one (they are separate objects). The visible ConcreteProperty is unaffected.
To make this work, you need to move the signal attachment + the slot out of the combo box object. The following is a replacement for the two parts —
class ConcreteStrengthComboBox(QtWidgets.QComboBox):
def __init__(self, parent = None):
super(ConcreteStrengthComboBox, self).__init__(parent)
self.addItems(["C12/15","C16/20","C20/25","C25/30","C30/37","C35/45","C40/50","C45/55",
"C50/60","C55/67","C60/75","C70/85","C80/95","C90/105"])
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
self.compressive_strength = ["12","16","20","25","30","35","40","45","50","55",
"60","70","80","90"]
class ConcreteStrengthInFo(QtWidgets.QWidget):
def __init__(self, parent=None):
super(ConcreteStrengthInFo, self).__init__(parent)
hbox = QtWidgets.QHBoxLayout()
concrete_strength = QtWidgets.QLabel("Concrete strength: ")
hbox.addWidget(concrete_strength)
self.concreteproperty = ConcreteProperty()
self.concretestrengthbox = ConcreteStrengthComboBox()
hbox.addWidget(self.concretestrengthbox)
self.concretestrengthbox.activated.connect(self.setdatastrength)
self.vlay = QtWidgets.QVBoxLayout()
self.vlay.addLayout(hbox)
self.vlay.addLayout(self.concreteproperty.concretestrength_lay)
#QtCore.pyqtSlot(int)
def setdatastrength(self, index):
it = self.concretestrengthbox.compressive_strength[index]
print(it)
self.concreteproperty.display_condata(it)
This works for me locally.

How to passing Value from a function to another class with python

Here I have 2 different classes called c_elementOptFrame (lets call it class a) and c_elementFigFrame (and this is class b). In class a, I have radio button object, these button will change an image in which I construct with label in class b, in other words, I wanted to change this image when I click those radio button. The radio button has been set up with method called react , in this method I wanted to pass a value (string) to class b, so that class b will use this value to change the image. But it doesn't work as I expected. The value has been passed to class b (I printed the value) but the image doesn't come up, I tried several ways but I still couldn't do it yet. so this is my code, please let me know if you have couple of suggestions or an alternative to do it. Thank you
code:
class c_elementOptFrame(QFrame):
def __init__(self, parent=None):
super(c_elementOptFrame,self).__init__()
self.setVisible(True)
self.setMaximumWidth(150)
self.setFrameShadow(QFrame.Plain)
self.setFrameShape(QFrame.Box)
self.setLineWidth(1)
self.setFrameStyle(QFrame.StyledPanel)
#layoutmanager
layout = QVBoxLayout()
#all objects inside this frame
strel_lab = QLabel("Element Types")
strel_lab.setContentsMargins(0,0,10,10)
group_box = QGroupBox('Structural Element')
opts_group = QButtonGroup()
opts_group.setExclusive(True)
beam_but = QRadioButton("Beams")
slab_but = QRadioButton("Slabs")
beam_but.toggled.connect(self.react_1)
slab_but.toggled.connect(self.react_2)
opts_group.addButton(beam_but)
opts_group.addButton(slab_but)
group_box.setLayout(layout)
concls_lab = QLabel("Concrete Class")
concls_lab.setContentsMargins(0,15,10,10)
concls_opt = QComboBox()
concls_opt.addItem("C30")
concls_opt.addItem("C40")
concls_opt.addItem("C50")
mod_but = QPushButton("Modify Parameter", self)
mod_but.clicked.connect(self.modifyParam)
create_but = QPushButton("Create Model", self)
create_but.setDisabled(False)
create_but.clicked.connect(self.nextFrame)
#add objects to layout
layout.addWidget(strel_lab)
layout.addWidget(beam_but)
layout.addWidget(slab_but)
layout.addWidget(concls_lab)
layout.addWidget(concls_opt)
layout.addWidget(mod_but)
layout.addStretch()
layout.addWidget(create_but)
self.setLayout(layout)
def react_1(self, enabled):
if enabled:
pict_path = 1
c_elementFigFrame(pict_path)
class c_elementFigFrame(QFrame):
def __init__(self, pict_path):
super(c_elementFigFrame,self).__init__()
self.setFrameShadow(QFrame.Plain)
self.setFrameShape(QFrame.Box)
self.setLineWidth(1)
self.setFrameStyle(QFrame.StyledPanel)
layout = QVBoxLayout()
pict = QLabel('Test')
pict.sizeHint()
pixmap = QPixmap()
if pict_path == 1:
print(True)
pixmap.load('beam.png')
pict.setPixmap(pixmap)
#else:
#pixmap = QPixmap(pict_path)
#pict.setPixmap(pixmap)
layout.addWidget(pict)
self.setLayout(layout)

Categories