I want to create an item for my QComboBox that displays a string and 4 pixmaps in a row (the final usage is so that the user can pick from a list of colour schemes).
Can anyone help me customise the QStandardItem to get this effect? I thought I could use the rows to do to it but I've not had much luck. This is what I've tried so far...
myComboBox = QtGui.QComboBox()
item = QtGui.QStandardItem()
item.setRowCount(4)
colour1 = QtGui.QPixmap(16, 16)
colour1 .fill(QtGui.QColor("red"))
colour2 = QtGui.QPixmap(16, 16)
colour2 .fill(QtGui.QColor("blue"))
colour3 = QtGui.QPixmap(16, 16)
colour3 .fill(QtGui.QColor("white"))
childitem1 = QtGui.QStandardItem(QtGui.QIcon(colour1), "1")
childitem2 = QtGui.QStandardItem(QtGui.QIcon(colour2), "2")
childitem3 = QtGui.QStandardItem(QtGui.QIcon(colour3), "3")
item.setChild(0, childitem1)
item.setChild(1, childitem2)
item.setChild(2, childitem3)
myComboBox.model().appendRow(item)
But I just get an empty item and none of the children are visible - there's a good chance I've completely misunderstood how this works :)
You have to create a QStandarItemModel, append your items to it, and at the end you have to set this model to your combobox with myComboBox.setModel().
Something like this
itemModel = QStandardItemModel()
# create your items as you want
itemModel.appendRow(your_items)
myComboBox.setModel(itemModel)
I've managed to get a sort of half solution by putting a table view into the combo box like this:
itemModel = QtGui.QStandardItemModel()
item1 = QtGui.QStandardItem("1")
item2 = QtGui.QStandardItem("2")
item3 = QtGui.QStandardItem("3")
itemModel.appendRow([item1, item2, item3])
myComboBox.setModel(itemModel)
tv = QtGui.QTableView()
tv.setModel(itemModel)
tv.horizontalHeader().setVisible(False)
tv.verticalHeader().setVisible(False)
tv.resizeColumnsToContents()
tv.setSelectionBehavior(QtGui.QAbstractItemView.SelectRows)
myComboBox.setView(tv)
It's a not 100% pretty but it just about does the job! Thanks for the help getting there.
Related
I want to remove the following:
I just want to show 'only' the file names.
This is my QTreeView Code:
self.model = QFileSystemModel()
self.model.setRootPath(QDir.rootPath())
self.model.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries | QDir.Dirs | QDir.Files)
self.proxy_model = QSortFilterProxyModel(recursiveFilteringEnabled = True, filterRole = QFileSystemModel.FileNameRole)
self.proxy_model.setSourceModel(self.model)
self.model.setReadOnly(False)
self.model.setNameFilterDisables(False)
self.indexRoot = self.model.index(self.model.rootPath())
self.treeView = QTreeView(self)
self.treeView.setModel(self.proxy_model)
self.adjust_root_index()
self.treeView.setRootIndex(self.indexRoot)
self.treeView.clicked.connect(self.on_treeView_clicked)
self.treeView.doubleClicked.connect(self.treeMedia_doubleClicked)
self.treeView.setDragDropMode(QAbstractItemView.InternalMove)
self.treeView.setAnimated(True)
self.treeView.setIndentation(20)
self.treeView.setSortingEnabled(True)
self.treeView.setDragEnabled(True)
self.treeView.setAcceptDrops(True)
self.treeView.setDropIndicatorShown(True)
self.treeView.setEditTriggers(QTreeView.NoEditTriggers)
self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
self.treeView.customContextMenuRequested.connect(self.showContextMenu)
I've tried some options from the PyQt5 API, like setHeader() But I couldn't figure out how it quite works. I'm not sure if setHeader() is even what I'm looking for.
You can hide the columns using the hideSection() method of the QHeaderView:
for i in range(1, self.treeView.model().columnCount()):
self.treeView.header().hideSection(i)
I need some assistance, because this problem simply doesn't make sense... Indentation is looking a bit off sorry for that...
self.myData = [["facebook-icon", "Facebook", str(self.mykeys[0][1]), "*" *len(self.passes[0])], ......
Only the first item in the table is getting populated, even though the rowCount prints out the number 3.. thats what is puzzling me.. would love someone trying out this code, I am a Python newbie
passAmount = len(self.myData)
print("There are %x items in myData" % (passAmount))
rowCount = self.tableWidget.rowCount()
print("There are %x items in the table" % (rowCount))
for row in range(0, rowCount):
cellText = self.tableWidget.itemAt(row,0).text()
if(cellText == "facebook-icon"):
self.tableWidget.itemAt(row, 0).setText("")
print(imagePaths[0])
fb = QPixmap(imagePaths[0]).scaledToWidth(20)
label = QLabel()
label.setPixmap(fb)
# label.setScaledContents(True)
self.tableWidget.setCellWidget(row, 0, label)
elif(cellText == "blogger-icon"):
...
self.tableWidget.setFont(self.font)
self.tableWidget.resizeColumnsToContents()
self.tableWidget.resizeRowsToContents()
self.tableWidget.doubleClicked.connect(self.on_table_click)
# Show widget
self.show()
Am I doing somethin wrong??
As I see you want to get elements from the first column, but itemAt() does not return the item given a row and column but to a geometric position, instead you should use the item() method. In addition we can reduce code using a dictionary:
dict_icons = {
"facebook-icon": imagePaths[0],
"blogger-icon": imagePaths[1]
}
for row in range(0, 3):
item = self.tableWidget.item(row, 0)
image_path = dict_icons.get(item.text())
if image_path is not None:
item.setText("")
pixmap = QPixmap(image_path).scaledToWidth(20)
label = QLabel(pixmap=pixmap)
self.tableWidget.setCellWidget(row, 0, label)
I'm trying to add a QTreeWidget with alternating row colours to a python panel in Houdini but getting these strange gaps in the dark alternations.
Has anyone seen this problem before and know how to fix it?
Thanks,
Mark
Houdini 17 here and it works fine with this code. You should post a sample of your code.
from hutil.Qt import QtWidgets
def onCreateInterface():
tree = QtWidgets.QTreeWidget()
tree.setAlternatingRowColors(True)
item1 = QtWidgets.QTreeWidgetItem(tree, ['item1'])
item11 = QtWidgets.QTreeWidgetItem(item1, ['item11'])
item111 = QtWidgets.QTreeWidgetItem(item11, ['item111'])
item1111 = QtWidgets.QTreeWidgetItem(item111, ['item1111'])
item2 = QtWidgets.QTreeWidgetItem(tree, ['item2'])
item21 = QtWidgets.QTreeWidgetItem(item2, ['item21'])
item211 = QtWidgets.QTreeWidgetItem(item21, ['item211'])
item212 = QtWidgets.QTreeWidgetItem(item21, ['item212'])
item213 = QtWidgets.QTreeWidgetItem(item21, ['item213'])
return tree
I am working on an Sonos Controller using the PyQT lib.
When i change to netxt or prev track, the labels are updated with the artist, title and album info. They are cut-off tho. Anyone experienced this before ? Its not a length issue, as the cutting off seems to change.
This is the code I update the labels with:
def currentTrackInfo(self):
currentTrackInfoDict = {}
currentZone = str(self.cb.currentText())
deviceDict = self.sonosZonesCoordinatorsIP()
for key, value in deviceDict.items():
if value == currentZone:
device = SoCo(key)
track = device.get_current_track_info()
current_title = track['title']
current_artist = track["artist"]
current_album = track["album"]
currentTrackInfoDict.update({"current_title": current_title})
currentTrackInfoDict.update({"current_artist": current_artist})
currentTrackInfoDict.update({"current_album": current_album})
self.artImage()
return currentTrackInfoDict
def updateTrackInfo(self):
self.artistlabel.clear
self.albumlabel.clear
self.titlelabel.clear
self.currentTrackInfoDict = self.currentTrackInfo()
self.artistlabel.setText("{}".format(self.currentTrackInfoDict["current_artist"]))
self.albumlabel.setText("{}".format(self.currentTrackInfoDict["current_album"]))
self.titlelabel.setText("{}".format(self.currentTrackInfoDict["current_title"]))
Here is a snippet
self.list_ctrl = wx.ListCtrl(self, size=(-1,100),
style=wx.LC_ICON|wx.LC_ALIGN_LEFT
)
il = wx.ImageList(16,16,True)
png = wx.ArtProvider.GetBitmap(wx.ART_FILE_OPEN,wx.ART_OTHER, (16,16))
il.Add(png)
self.list_ctrl.AssignImageList(il,wx.IMAGE_LIST_NORMAL)
sizer = wx.BoxSizer(wx.VERTICAL)
sizer.Add(self.list_ctrl, 0, wx.ALL|wx.EXPAND, 5)
self.SetSizer(sizer)
self.list_ctrl.InsertImageStringItem(0,"1",0)
self.list_ctrl.InsertImageStringItem(1,"2",0)
My problem is that the icons appear to the top of the text which should not happen because I put wx.LC_ALIGN_LEFT in the style. I would like the icons to appear left of the text.
Another problem is that, I want one element per row. In my code it is almost like one element per column.
Can anyone help me with any of these problems?
Thanks.
Looking at the wxPython demo for the ListCtrl, it looks like they use SetImageList() instead of AssignImageList(). Not sure what the difference is though. I don't see where you're inserting any text though. You'd need to use SetStringItem to put text in the other columns from what I can see.
EDIT: Code from wxPython Demo package, ListCtrl demo:
self.il = wx.ImageList(16, 16)
self.idx1 = self.il.Add(images.Smiles.GetBitmap())
self.sm_up = self.il.Add(images.SmallUpArrow.GetBitmap())
self.sm_dn = self.il.Add(images.SmallDnArrow.GetBitmap())
And then we add data / images to the widget
def PopulateList(self):
if 0:
# for normal, simple columns, you can add them like this:
self.list.InsertColumn(0, "Artist")
self.list.InsertColumn(1, "Title", wx.LIST_FORMAT_RIGHT)
self.list.InsertColumn(2, "Genre")
else:
# but since we want images on the column header we have to do it the hard way:
info = wx.ListItem()
info.m_mask = wx.LIST_MASK_TEXT | wx.LIST_MASK_IMAGE | wx.LIST_MASK_FORMAT
info.m_image = -1
info.m_format = 0
info.m_text = "Artist"
self.list.InsertColumnInfo(0, info)
info.m_format = wx.LIST_FORMAT_RIGHT
info.m_text = "Title"
self.list.InsertColumnInfo(1, info)
info.m_format = 0
info.m_text = "Genre"
self.list.InsertColumnInfo(2, info)
items = musicdata.items()
for key, data in items:
index = self.list.InsertImageStringItem(sys.maxint, data[0], self.idx1)
self.list.SetStringItem(index, 1, data[1])
self.list.SetStringItem(index, 2, data[2])
self.list.SetItemData(index, key)