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
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 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"]))
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.
I am using code in wxPython to show images.
I created a screen with 2 panels, one left and right.
In one of the panels (randomly chosen), I want do display an image for exactly 150ms.
How can I program this? I am relatively new to Python, and I don't find any clear way on the internet.
My code for now (without the 150ms):
import wxversion
wxversion.select("3.0")
import wx
import random
import timeclass Screen_1(wx.Dialog):
ri = 0
def __init__(self,parent,id,title):
wx.Dialog.__init__(self,parent,id,title,size=(400,300))
self.randomImage = random.randrange(1,3)
self.randomSlot = random.randrange(1,3)
Screen_1.ri = self.randomImage
if(self.randomSlot == 1):
self.side = 'Left'
else:
self.side = 'Right'
file = open('User.txt','a')
panel_left = wx.Panel(self,11,(-1,-1),(200,200))
self.picture_left = wx.StaticBitmap(panel_left)
font = wx.Font(13,wx.DEFAULT,wx.NORMAL,wx.BOLD)
panel_centre = wx.Panel(self,12,(200,70),(10,100))
msg = wx.StaticText(panel_centre,-1,'+',size=(10,100))
msg.SetFont(font)
panel_right = wx.Panel(self,13,(210,0),(200,200))
self.picture_right = wx.StaticBitmap(panel_right)
**self.imageName = 'im_'+str(self.randomImage)+'.png'**
if self.randomSlot == 1:
self.picture_left.SetBitmap(wx.Bitmap(self.imageName))
else:
self.picture_right.SetBitmap(wx.Bitmap(self.imageName))
wx.FutureCall(1000,self.Destroy)
self.Centre()
self.ShowModal()
def OnClick(self,event):
self.Close()
Thanks a lot!
def OnTimeUp(self,e):
#change images
self.timer.Start(15,oneShot=True) # if you want to call it again in 15 ms
def StartTimer(self):
self.timer = wx.Timer()
self.timer.Bind(wx.EVT_TIMER,self.OnTimeUp)
self.timer.Start(15,oneShot=True)
something like that ... although 15ms is very fast ...
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)