Related
So I'm very confused here. When I use the scrapy shell and input the xpath the correct data is returned, but when I set that same xpath equal to a variable within the script, it outputs a blank. I'm really not sure what is going on.
import scrapy
class FestivalSpider(scrapy.Spider):
name = 'basketball'
custom_settings = {
"DOWNLOAD_DELAY": 3,
"CONCURRENT_REQUESTS_PER_DOMAIN": 3,
"HTTPCACHE_ENABLED": True
}
start_urls = [
'http://www.basketball-reference.com/leagues/NBA_2017_per_game.html'
]
def parse(self, response):
start_urls = [
'http://www.basketball-reference.com/leagues/NBA_2017_per_game.html']
for href in start_urls:
yield scrapy.Request(
url=href,
callback=self.parse_festival,
meta={'url': href}
)
def parse_festival(self, response):
url = response.request.meta['url']
name = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "player"]/a/text()').extract()
pos = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "pos"]/text()').extract()
age = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "age"]/text()').extract()
#team = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "team_id"]/text()').extract()
games = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "g"]/text()').extract()
games_s = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "gs"]/text()').extract()
fg_per_mp = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg_per_mp"]/text()').extract()
#fga_per_mp = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fga_per_mp"]/text()').extract()
#fg_pct = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg_pct"]/text()').extract()
#fg3_per_mp = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg3_per_mp"]/text()').extract()
#fg3a_per_mp = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg3a_per_mp"]/text()').extract()
#fg3_pct = response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg3_pct"]/text()').extract()
#location = (
# response.xpath('//div[#id="festival-basics"]/text()').extract()[3])
#dates = (
# response.xpath('//div[#id="festival-basics"]/text()').extract()[5])
#tickets = (
# response.xpath('//div[#id="festival-basics"]/text()').extract()[7])
#website = (
# response.xpath(
# '//div[#id="festival-basics"]/a/#href').extract()[0]
#)
#logo = (
# response.xpath(
# '//div[#id="festival-basics"]/img/#src').extract()[0]
#)
#lineup = (
# response.xpath(
# '//div[#class="lineupguide"]/ul/li/text()').extract() +
# response.xpath(
# '//div[#class="lineupguide"]/ul/li/a/text()').extract()
#)
print(response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg_per_mp"]/text()').extract())
yield {
'url': url,
'name': name,
'pos': pos,
'age' : age,
'games' : games,
'games_s': games_s,
'fg_per_mp': fg_per_mp
#'fga_per_mp': fga_per_mp,
#'fg_pct': fg_pct,
#'fg3_per_mp': fg3_per_mp,
#'fg3a_per_mp': fg3a_per_mp
#'team' : team
#'location': location,
#'dates': dates,
#'tickets': tickets,
#'website': website,
#'logo': logo,
#'lineup': lineup
}
The item in question is the fg_per_mp, when I use the response.xpath('//tr[#class = "full_table"]/td[#data-stat = "fg_per_mp"]/text()').extract() in the shell it works, but the same line in the script returns an empty list.
What am I doing wrong?
import random
from tkinter import *
class Spinner(object):
#staticmethod
def getSpin():
newSpin = random.randint(1,6)
return newSpin
class Player(object):
def __init__(self,name):
self.position = 1
self.name = name
def setName(self,name):
self.name = name
def changePosition(self,number):
self.position = self.position + number
def setPosition(self,pos):
self.position = pos
return self.position
def getPosition(self):
return self.position
def getName(self):
return self.name
def spin(self):
newSpin = Spinner.getSpin()
self.position = self.position + newSpin
print(str(self.name) + "'s spin was: " + str(newSpin))
class Path(object):
#staticmethod
def buildLadders():
ladders = [[0 for x in range(2)] for x in range(9)]
ladders[0][0] = 2
ladders[0][1] = 9
ladders[1][0] = 8
ladders[1][1] = 11
return ladders
#staticmethod
def buildChutes():
chutes = [[0 for x in range(2)] for x in range(10)]
chutes[0][0] = 9
chutes[0][1] = 3
chutes[1][0] = 12
chutes[1][1] = 6
return chutes
class Check(Player):
def __init__(self):
super(Check,self).__init__()
def checkLadders(self):
ladders = Path.buildLadders()
for i in range(0,len(ladders),1):
if self.getPosition() == ladders[i][0]:
self.position = self.setPosition(ladders[i][1])
print(str(self.name) + " Landed on a Ladder! from " + \
str(ladders[i][0]) +" to " + str(ladders[i][1]))
def newPosition(self):
return self.position
def checkChutes(self):
chutes = Path.buildChutes()
for i in range(0,len(chutes),1):
if self.getPosition() == chutes[i][0]:
self.position = self.setPosition(chutes[i][1])
print(str(self.name) + " Landed on a Chutes!")
class Match_Position(Player):
def __init__(self,name):
super(Match_Position,self).__init__(name)
self.match = [[70,235],
[180,235],
[290,235],
[400, 235],
[400, 140],
[290, 140],
[180, 140],
[70, 140],
[70, 45],
[180, 45],
[290, 45],
[400, 45]]
self.name = name
self.players = Player(self.name)
self.pos = self.players.getPosition()
self.position_actual = []
self.__str__()
self.actualpos()
def __str__(self):
for j in range(len(self.match)):
if self.pos == (j+1):
self.position_actual.append(self.match[j][0])
self.position_actual.append(self.match[j][1])
def actualpos(self):
return self.position_actual
class Display(object):
def __init__(self,master,img,name):
canvas_width = 650
canvas_height = 300
self.name = name
print(self.name)
self.pos = Match_Position(self.name).actualpos()
print(self.pos)
self.canvas = Canvas(master, width = canvas_width, height = canvas_height, bg = "yellow")
self.canvas.grid(padx=0, pady=0)
self.canvas.create_image(300,150,anchor=CENTER, image = img)
self.animate(master)
def animate(self,master):
Button(master, text= "ROLL", command=self.say_hello(self.name[0])).grid( row=3, column=0, sticky=E)
Button(master, text= "ROLL", command=self.say_hello1(self.name[1])).grid( row=3, column=1, sticky=E)
def say_hello(self,name):
self.name = name
self.name = Player(self.name)
self.name.spin()
Check.checkLadders(self.name)
Check.checkChutes(self.name)
x = self.pos[0]
y = self.pos[1]
self.canvas.create_oval(x,y,x+20,y+20, fill='blue')
def say_hello1(self,name):
self.name = name
self.name = Player(self.name)
self.name.spin()
Check.checkLadders(self.name)
Check.checkChutes(self.name)
x = self.pos[0]
y = self.pos[1]
self.canvas.create_oval(x,y,x+20,y+20, fill='red')
class BounceController(object):
def __init__(self):
master = Tk()
master.title("Snake and Ladder")
master.geometry("700x350")
img = PhotoImage( file = "puzzlor-chutes-and-ladders.gif" )
name = ['n','s']
Display(master,img,name).animate(master)
master.mainloop()
def main():
BounceController()
main()
It printed out this, but the error:
"'Player' object does not support indexing" pop out.
What is object does not support indexing error is?
And when I click the button, the oval does not actually move.
And using tkinter Button, I can call the method, right?
But by doing so, if I want to make for example, clicking the button, result to the oval moving to different location, how do I achieve that? Since as my code, above, the oval does not move eventhough the button is clicked.
Thanks. Since I'm quite new to python and programming, any help would be such a gratitude.
Indexing is when you suffix an object with [n], where n is an int. Here is how to reproduce the message.
>>> class C: pass
>>> C()[1]
Traceback (most recent call last):
File "<pyshell#21>", line 1, in <module>
C()[1]
TypeError: 'C' object does not support indexing
The File entry above the error message tells you the line number and expression that gave the error. Someplace in your code, as indicated by the traceback you did not show us, you have x[n], where x in an instance of the Player class you defined.
An object is subscriptable if and only if it has a __getitem__ method, which Player does not have and should not have.
I created a Class and created many instances and stored it into an array called messages
If I type,
print messages[0]
It gives
#<SMSMessage:0x00000001681d88 #id=29185, #account_id=1565, #upload_id=0, #txaction_type_id=9, #txid=0, #finanalytics_txid=1565,
#date_posted=2015-05-13 17:58:01 +0530, #sequence=1, #sic_code=0,
#amount=-1802.0, #raw_name="MERLINS", #filtered_name="MERLINS",
#cleaned_name="NULL", #merchant_id="NULL", #memo="NULL",
#check_num="NULL", #ref_num="NULL", #balance=0.0, #created_at=2015-05-13 18:03:30 +0530,
#updated_at=2015-05-13 18:08:17 +0530, #status="0", #tagged=0, #merged_with_txaction_id=0, #note="NULL", #usd_amount=0.0, #attachment_ids="NULL", #automatch=0, #merchant_name="MERLINS", #tag_names=nil, #transfer_txaction_id=0, #fi_date_posted=2015-05-13 17:58:01 +0530, #transaction_status_id=0, #mc_code="NULL", #provider_txn_type="NULL", #latitude=19.09686, #longitude=72.8537753, #sync_status=31, #sec_account_id=0, #associated_sms_id=130672, #account_key="YzI5ZDUyNWY5NmYwNWFiNjJiYmE1YTk4Y2VkYTBjYTZmOGM5ZTI0NzE2MzU2MzAwMmU2OWU2MzNiYmQ2YTZhMA==", #id_on_client=229, #sync_delete_status=0,
#matching_bill_id=0, #mapped_account_number=0, #additional_description="NULL", #category_id=45, #data_processing_flag=4,
#derived_description="NULL", #final_description="NULL", #derived_merchant="Merlins Bar", #final_merchant="NULL",
#tentative_location_flag=-1, #tentative_latitude="-90.00000000000", #tentative_longitude="-90.00000000000", #mongo_merchant_id="102", #parent_category_id=40, #raw_description="NULL", #formatted_description="NULL", #associated_sms_client_id=779, #account_client_id=4>
If i try to access the ID by typing,
print messages[0].id
It gives me an error
NoMethodError: undefined method `id' for #<SMSMessage:0x00000001681d88>
How do I resolve this ?
PS - The SMSMessage Class Code is
class SMSMessage
def initialize(id,account_id,upload_id,txaction_type_id,txid,finanalytics_txid,date_posted,sequence,sic_code,amount,raw_name,filtered_name,cleaned_name,merchant_id,memo,check_num,ref_num,balance,created_at,updated_at,status,tagged,merged_with_txaction_id,note,usd_amount,attachment_ids,automatch,merchant_name,tag_names,transfer_txaction_id,fi_date_posted,transaction_status_id,mc_code,provider_txn_type,latitude,longitude,sync_status,sec_account_id,associated_sms_id,account_key,id_on_client,sync_delete_status,matching_bill_id,mapped_account_number,additional_description,category_id,data_processing_flag,derived_description,final_description,derived_merchant,final_merchant,tentative_location_flag,tentative_latitude,tentative_longitude,mongo_merchant_id,parent_category_id,raw_description,formatted_description,associated_sms_client_id,account_client_id)
#id = id.to_i
#account_id = account_id.to_i
#upload_id = upload_id.to_i
#txaction_type_id = txaction_type_id.to_i
#txid = txid.to_i
#finanalytics_txid = finanalytics_txid.to_i
#date_posted = Time.parse(date_posted)
#sequence = sequence.to_i
#sic_code = sic_code.to_i
#amount = amount.to_f
#raw_name = raw_name
#filtered_name = filtered_name
#cleaned_name = cleaned_name
#merchant_id = merchant_id
#memo = memo
#check_num = check_num
#ref_num = ref_num
#balance = balance.to_f
#created_at = Time.parse(created_at)
#updated_at = Time.parse(updated_at)
#status = status
#tagged = tagged.to_i
#merged_with_txaction_id = merged_with_txaction_id.to_i
#note = note
#usd_amount = usd_amount.to_f
#attachment_ids = attachment_ids
#automatch = automatch.to_i
#merchant_name = merchant_name
#tag_names = tag_names
#transfer_txaction_id = transfer_txaction_id.to_i
#fi_date_posted = Time.parse(fi_date_posted)
#transaction_status_id = transaction_status_id.to_i
#mc_code = mc_code
#provider_txn_type = provider_txn_type
#latitude = latitude.to_f
#longitude = longitude.to_f
#sync_status = sync_status.to_i
#sec_account_id = sec_account_id.to_i
#associated_sms_id = associated_sms_id.to_i
#account_key = account_key
#id_on_client = id_on_client.to_i
#sync_delete_status = sync_delete_status.to_i
#matching_bill_id = matching_bill_id.to_i
#mapped_account_number = mapped_account_number.to_i
#additional_description = additional_description
#category_id = category_id.to_i
#data_processing_flag = data_processing_flag.to_i
#derived_description = derived_description
#final_description = final_description
#derived_merchant = derived_merchant
#final_merchant = final_merchant
#tentative_location_flag = tentative_location_flag.to_i
#tentative_latitude = tentative_latitude.to_f
#tentative_longitude = tentative_longitude.to_f
#mongo_merchant_id = mongo_merchant_id
#parent_category_id = parent_category_id.to_i
#raw_description = raw_description
#formatted_description = formatted_description
#associated_sms_client_id = associated_sms_client_id.to_i
#account_client_id = account_client_id.to_i
end
end
Since you do not define accessor methods for object attributes, you should use instance_variable_get:
messages[0].instance_variable_get(:#id)
To be able to read id attribute (that is messages[0].id) you would want to add
attr_reader :id
to your model. If you will need to write this attribute, you would define attr_writer :id.
For both (read and write) there is a attr_accessor :id.
I am to create a simple image viewer using wxPython. I am using a panel and a button upon which by clicking a picture would be shown from a directory (Images). Below is the code. I have taken pieces from different websites.
My question is if I maximize the window, the picture viewer as well as the button remain same. I want the picture viewer to increase as well.
Another thing is, after I press the "Load" button, it moves to the left. How do I fix these two problems?
I understand for those 2 above questions, this so big program might be unnecessary. I am a newbie to Python.
Thanks in advance.
import wx, os
class Panel1(wx.Panel):
def __init__(self, *args, **kwds):
wx.Panel.__init__(self, *args, **kwds)
self.jpgs = self.GetJpgList("./Images")
self.CurrentJpg = 0
self.MaxImageSize = 200
self.img = wx.EmptyImage(self.MaxImageSize,self.MaxImageSize)
self.imageCtrl = wx.StaticBitmap(self, wx.ID_ANY, wx.BitmapFromImage(self.img))
self.button_1 = wx.Button(self, wx.ID_ANY, "Load")
self.Bind(wx.EVT_BUTTON, self.OnLoad, self.button_1)
self.__do_layout()
self.Layout()
def GetJpgList(self, dir):
jpgs = [f for f in os.listdir(dir) if f[-4:] == ".JPG"]
return [os.path.join(dir, f) for f in jpgs]
def __do_layout(self):
sizer_1 = wx.BoxSizer(wx.HORIZONTAL)
sizer_2 = wx.BoxSizer(wx.VERTICAL)
sizer_1.Add((1,1),1)
sizer_1.Add(self.imageCtrl, 0, wx.ALL|wx.EXPAND, 5)
sizer_1.Add((1,1),1)
sizer_1.Add(wx.StaticLine(self, wx.ID_ANY), 0, wx.ALL|wx.EXPAND, 5)
sizer_2.Add(self.button_1, 0, wx.ALL|wx.TOP, 5)
sizer_1.Add(sizer_2, 0, wx.ALL, 5)
self.SetSizer(sizer_1)
sizer_1.Fit(self)
def OnNext(self, event):
path = self.jpgs[self.CurrentJpg]
self.Img = wx.Image(path, wx.BITMAP_TYPE_ANY)
W = self.Img.GetWidth()
H = self.Img.GetHeight()
if W > H:
NewW = self.MaxImageSize
NewH = self.MaxImageSize * H / W
else:
NewH = self.MaxImageSize
NewW = self.MaxImageSize * W / H
self.Img = self.Img.Scale(NewW,NewH)
self.imageCtrl.SetBitmap(wx.BitmapFromImage(self.Img))
#self.Fit()
#self.Layout()
self.Refresh()
self.CurrentJpg += 1
if self.CurrentJpg > len(self.jpgs) -1:
self.CurrentJpg = 0
# end of class Panel1
class Frame1(wx.Frame):
def __init__(self, *args, **kwds):
wx.Frame.__init__(self, *args, **kwds)
self.__set_properties()
self.__do_layout()
def __set_properties(self):
self.SetTitle("Picture")
def __do_layout(self):
panel1 = Panel1(self)
self.sizer = wx.BoxSizer(wx.VERTICAL)
self.sizer.Add(panel1, 1, wx.EXPAND)
self.SetSizer(self.sizer)
self.sizer.Fit(self)
self.Layout()
self.Centre()
# end of class Frame1
class Game1(wx.App):
def OnInit(self):
wx.InitAllImageHandlers()
frame1 = Frame1(None, wx.ID_ANY, "")
self.SetTopWindow(frame1)
frame1.Show()
return 1
# end of class Game1
if __name__ == "__main__":
game1 = Game1(0)
game1.MainLoop()
To make the image resize itself on maximize, you will need to catch wx.EVT_MAXIMIZE. Then in your event handler, you'll need to call your function that updates the image control you created. You may need to use the Frame's size to help you determine what your MaxImageSize should be.
For the load button issue, you may need to call the sizer or the widget's parent's Layout() method.
my purpose is to display an different icon in treeview list when a specific postion(row, column) match a value. eg: (row, 2) is dir or file, will diplay different icon. because this is not used in local filesystem, QDir or Qfilesystem model not suite for this.
i know a bit on MVC that controller display in view, make model as data interface api. but i do not how to make it works on specific position(row ,col) as my expect.
i have tried to add args in ImageDelegate(like pass icon file name to it), but failed maybe due to its parent Class not accept more args.
hope someone can give me some light.
class ImageDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
QtGui.QStyledItemDelegate.__init__(self, parent)
#self.icon =icon
def paint(self, painter, option, index):
#painter.fillRect(option.rect, QtGui.QColor(191,222,185))
# path = "path\to\my\image.jpg"
path = "icon1.png"
image = QtGui.QImage(str(path))
pixmap = QtGui.QPixmap.fromImage(image)
pixmap.scaled(16, 16, QtCore.Qt.KeepAspectRatio)
painter.drawPixmap(option.rect.x(), option.rect.y(), pixmap)
and i can use this delegate in my view. but it will change all line in specific column.
def init_remotetreeview(self):
self.model = myModel(self.remote_Treeview)
for therow in range(self.model.rowCount(QModelIndex())) :
print self.model.data(self.model.index(therow, 2, QtCore.QModelIndex()),Qt.DisplayRole).toString() # i do check the value will used to load correct icon.
self.remote_Treeview.setItemDelegate(ImageDelegate(self)) # this change all lines
self.remote_Treeview.setModel(self.model)
In fact, your have some light in your code, isn't it ? (Just kidding.)
Your have right way to use QtGui.QStyledItemDelegate. I have reference how to implement it (But, C++ only). 'Star Delegate Example', 'QItemDelegate Class Reference C++' and 'QItemDelegate Class Reference PyQt4';
Keyword : Your have to implement paint draw your element what your want (I think this is your want.)
Little example, Hope is help;
import sys
from PyQt4 import QtCore, QtGui
from functools import partial
class QCustomDelegate (QtGui.QItemDelegate):
signalNewPath = QtCore.pyqtSignal(object)
def createEditor (self, parentQWidget, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
editorQWidget = QtGui.QPushButton(parentQWidget)
editorQWidget.released.connect(partial(self.requestNewPath, indexQModelIndex))
return editorQWidget
else:
return QtGui.QItemDelegate.createEditor(self, parentQWidget, optionQStyleOptionViewItem, indexQModelIndex)
def setEditorData (self, editorQWidget, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
textQString = indexQModelIndex.model().data(indexQModelIndex, QtCore.Qt.EditRole).toString()
editorQWidget.setText(textQString)
else:
QtGui.QItemDelegate.setEditorData(self, editorQWidget, indexQModelIndex)
def setModelData (self, editorQWidget, modelQAbstractItemModel, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
textQString = editorQWidget.text()
modelQAbstractItemModel.setData(indexQModelIndex, textQString, QtCore.Qt.EditRole)
else:
QtGui.QItemDelegate.setModelData(self, editorQWidget, modelQAbstractItemModel, indexQModelIndex)
def updateEditorGeometry(self, editorQWidget, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
editorQWidget.setGeometry(optionQStyleOptionViewItem.rect)
else:
QtGui.QItemDelegate.updateEditorGeometry(self, editorQWidget, optionQStyleOptionViewItem, indexQModelIndex)
def requestNewPath (self, indexQModelIndex):
self.signalNewPath.emit(indexQModelIndex)
def paint (self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
textQString = indexQModelIndex.model().data(indexQModelIndex, QtCore.Qt.EditRole).toString()
painterQPainter.drawPixmap (
optionQStyleOptionViewItem.rect.x(),
optionQStyleOptionViewItem.rect.y(),
QtGui.QPixmap(textQString).scaled(180, 180, QtCore.Qt.KeepAspectRatio))
else:
QtGui.QItemDelegate.paint(self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex)
class QCustomTreeWidget (QtGui.QTreeWidget):
def __init__(self, parent = None):
super(QCustomTreeWidget, self).__init__(parent)
self.setColumnCount(1)
myQCustomDelegate = QCustomDelegate()
self.setItemDelegate(myQCustomDelegate)
myQCustomDelegate.signalNewPath.connect(self.getNewPath)
def addMenu (self, path, parentQTreeWidgetItem = None):
if parentQTreeWidgetItem == None:
parentQTreeWidgetItem = self.invisibleRootItem()
currentQTreeWidgetItem = QtGui.QTreeWidgetItem(parentQTreeWidgetItem)
currentQTreeWidgetItem.setData(0, QtCore.Qt.EditRole, path)
currentQTreeWidgetItem.setFlags(currentQTreeWidgetItem.flags() | QtCore.Qt.ItemIsEditable)
for i in range(self.columnCount()):
currentQSize = currentQTreeWidgetItem.sizeHint(i)
currentQTreeWidgetItem.setSizeHint(i, QtCore.QSize(currentQSize.width(), currentQSize.height() + 200))
def getNewPath (self, indexQModelIndex):
currentQTreeWidgetItem = self.itemFromIndex(indexQModelIndex)
pathQStringList = QtGui.QFileDialog.getOpenFileNames()
if pathQStringList.count() > 0:
textQString = pathQStringList.first()
currentQTreeWidgetItem.setData(indexQModelIndex.column(), QtCore.Qt.EditRole, textQString)
print textQString
class QCustomQWidget (QtGui.QWidget):
def __init__ (self, parent = None):
super(QCustomQWidget, self).__init__(parent)
self.myQCustomTreeWidget = QCustomTreeWidget(self)
self.allQHBoxLayout = QtGui.QHBoxLayout()
self.allQHBoxLayout.addWidget(self.myQCustomTreeWidget)
self.setLayout(self.allQHBoxLayout)
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter01.jpg''')
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter02.jpg''')
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter04.jpg''')
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter05.jpg''')
app = QtGui.QApplication([])
myQCustomQWidget = QCustomQWidget()
myQCustomQWidget.show()
sys.exit(app.exec_())
Note: In same way to implement QTreeView, but different is set values only.
If your want to show image by path in some index (In this case : 2nd). Your can find it by using QModelIndex QAbstractItemModel.index (self, int row, int column, QModelIndex parent = QModelIndex()), And do want your want.
Example;
import sys
from PyQt4 import QtCore, QtGui
class QCustomDelegate (QtGui.QItemDelegate):
def paint (self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 3:
currentQAbstractItemModel = indexQModelIndex.model()
iconQModelIndex = currentQAbstractItemModel.index(indexQModelIndex.row(), 1, indexQModelIndex.parent())
pathQString = currentQAbstractItemModel.data(iconQModelIndex, QtCore.Qt.EditRole).toString()
iconQPixmap = QtGui.QPixmap(pathQString)
if not iconQPixmap.isNull():
painterQPainter.drawPixmap (
optionQStyleOptionViewItem.rect.x(),
optionQStyleOptionViewItem.rect.y(),
iconQPixmap.scaled(20, 20, QtCore.Qt.KeepAspectRatio))
else:
QtGui.QItemDelegate.paint(self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex)
myQApplication = QtGui.QApplication([])
myQTreeView = QtGui.QTreeView()
headerQStandardItemModel = QtGui.QStandardItemModel()
headerQStandardItemModel.setHorizontalHeaderLabels([''] * 4)
myQTreeView.setModel(headerQStandardItemModel)
# Set delegate
myQCustomDelegate = QCustomDelegate()
myQTreeView.setItemDelegate(myQCustomDelegate)
# Append data row 1
row1QStandardItem = QtGui.QStandardItem('ROW 1')
row1QStandardItem.appendRow([QtGui.QStandardItem(''), QtGui.QStandardItem('1.jpg'), QtGui.QStandardItem(''), QtGui.QStandardItem('')])
headerQStandardItemModel.appendRow(row1QStandardItem)
# Append data row 2
row2QStandardItem = QtGui.QStandardItem('ROW 2')
row2QStandardItem.appendRow([QtGui.QStandardItem(''), QtGui.QStandardItem('2.png'), QtGui.QStandardItem(''), QtGui.QStandardItem('')])
headerQStandardItemModel.appendRow(row2QStandardItem)
myQTreeView.show()
sys.exit(myQApplication.exec_())
experimental result:
Note: I have image 1.jpg, 2.png.