I need use Ultimatelistctrl to icon with hyperline.
In Ultimatelistctrl API, it mentioned
"Hyperlink-type items and subitems: they look like an hyperlink, with the proper mouse cursor on hovering;"
But there is no working sample.
I create below render code. DrawSubItem function is called success. But OnMouseEvent is never called.
How can I bind user click to OnMouseEvent function
class CustomizedRenderer(object):
def __init__(self, parent, fileName):
self.parent = parent
self.fileName = fileName
self.normalFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
self.normalFont.SetPointSize(self.normalFont.GetPointSize() + 1)
self.smallerFont = wx.SystemSettings.GetFont(wx.SYS_DEFAULT_GUI_FONT)
self.greyColour = wx.SystemSettings.GetColour(wx.SYS_COLOUR_GRAYTEXT)
fileType = wx.TheMimeTypesManager.GetFileTypeFromExtension(extension)
bmp = wx.Bitmap(os.path.join(bitmapDir, "empty_icon.png"), wx.BITMAP_TYPE_PNG)
bmp = wx.IconFromBitmap(bmp)
self.icon = bmp
self.description = convert(fileType.GetDescription())
def OnMouseEvent(self, e):
if e.LeftUp():
webbrowser.open_new("http://www.google.com")
e.Skip()
def DrawSubItem(self, dc, rect, line, highlighted, enabled):
***********************
def GetLineHeight(self):
***********************
def GetSubItemWidth(self):
***********************
I am able to make it works after change C:\Python27\Lib\site-packages\wx-2.9.5-msw\wx\lib\agw\ultimatelistctrl.py
The change is add some logic on ultimatelistctrl.py onMouse() and then call your module code.
Related
I'm trying to get back into Python and I'm once again stuck with this problem I've had before of making objects accessible to one another. In this simple example I am displaying a panel with a button and a text box. Clicking on the text box calls a function which queries a database and returns a cursor with the retrieved data. I need to make it so that either the LookupSQL function or the ShowClientData function can write this output, in a loop, to the Text box. The TextBox (outputBox) is unknown to any other functions currently. How do I make it so that the other functions know what it is?
import wx
import pypyodbc
conn = pypyodbc.connect(driver='{SQL Server}', server='.', database='TheDB', uid='sa', pwd='Pass')
class Audit(wx.Frame):
def __init__(self, *args, **kwargs):
super(Example, self).__init__(*args, **kwargs)
self.InitUI()
def InitUI(self):
panel = wx.Panel(self)
hbox = wx.BoxSizer()
sizer = wx.GridSizer(6,1,2,2)
btn1 = wx.Button(panel, label='Clients')
outputBox = wx.TextCtrl(panel, -1, style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
sizer.AddMany([btn1, btn2, btn3, btn4, btn5, btn6])
hbox.Add(sizer, 0, wx.ALL, 15)
hbox.Add(outputBox, 1, wx.EXPAND)
panel.SetSizer(hbox)
btn1.Bind(wx.EVT_BUTTON, self.ShowClientData)
self.SetSize((800, 600))
self.SetTitle('Audit View')
self.Centre()
self.Show(True)
def ShowClientData(self, event):
SQL = 'select * from V_UpdatedClient'
recursor = lookupSQL(SQL)
for row in recursor:
rChange = row[0]
rItemType = row[1]
rPK = row[2]
rItemCode = row[3]
rFieldName = row[4]
rOldValue = row[5]
rNewValue = row[6]
rUpdateDate = row[7]
rUserName = row[8]
print('%s %s %s %s %s %s %s %s %s' % (rChange, rItemType, rPK, rItemCode, rFieldName, rOldValue, rNewValue, rUpdateDate, rUserName))
def lookupSQL(SQLString):
cursor = conn.cursor()
cursor.execute(SQLString)
return cursor
cursor.close()
def main():
ex = wx.App()
Audit(None)
ex.MainLoop()
if __name__ == '__main__':
main()
What you are looking for is called data attributes.
self.outputBox = wx.TextCtrl(panel, -1, style = wx.TE_MULTILINE|wx.TE_READONLY|wx.HSCROLL)
And then within ShowClientData you can write
self.outputBox.AppendText("some text")
As long as you have that self reference, you can access its attributes.
Edit:
When you do the above change, you can't refer to the text box by just outputBox anymore, you should instead access it via self:
hbox.Add(self.outputBox, 1, wx.EXPAND)
Declaring it as globally is very bad!
Could you please help me in solving this issue as i am a python PyQt beginner ...i have created a simple application with python PyQt4 for a simple math calculations and having the result in textEdit2 and textEdit3 every thing went fine when i click on calculate push button, values appear in the above textedits...what i want is to save the results on the same text edits so that next time when i open the application and open the data file i find every thing in place. I created the save and open actions...but it saves all the results in the same text edit..
i am attaching my code and also the main window with results that needed to be saved and another shot after saving and opening the application and having all the results in one textedit
enter code here
import sys
from PyQt4 import QtCore, QtGui, uic
import os #os used to interface with windows
import datetime as dt
import pickle
qtCreatorFile = "save.ui" # Enter ui file here
Ui_MainWindow, QtBaseClass = uic.loadUiType(qtCreatorFile)
class MyApp(QtGui.QMainWindow, Ui_MainWindow):
def __init__(self):
super (MyApp,self).__init__()
Ui_MainWindow.__init__(self)
self.setupUi(self)
self.initUI()
self.calc.clicked.connect(self.Bss)
def Bss (self):
x = float(self.textEdit.toPlainText())
y = float(self.textEdit1.toPlainText())
z= x+y
w= x**2
z_string = str(z) #convert z value to a string then add this string to textEdit and set as Text
self.textEdit2.setText(z_string)
w_string = str(w)
self.textEdit3.setText(w_string)
def initUI(self): #QAction class insert New,action save in the main menue bar
newAction = QtGui.QAction('New', self)
newAction.setShortcut('Ctrl+N')
newAction.setStatusTip('Create new file')
newAction.triggered.connect(self.newFile)
saveAction = QtGui.QAction('Save as', self)
saveAction.setShortcut('Ctrl+S')
saveAction.setStatusTip('Save current file')
saveAction.triggered.connect(self.saveFile)
openAction = QtGui.QAction('Open', self)
openAction.setShortcut('Ctrl+O')
openAction.setStatusTip('Open a file')
openAction.triggered.connect(self.openFile)
closeAction = QtGui.QAction('Close', self)
closeAction.setShortcut('Ctrl+Q')
closeAction.setStatusTip('Close Notepad')
closeAction.triggered.connect(self.close)
menubar = self.menuBar()
fileMenu = menubar.addMenu('&File')
fileMenu.addAction(newAction)
fileMenu.addAction(saveAction)
fileMenu.addAction(openAction)
fileMenu.addAction(closeAction)
self.show()
self.statusBar()
def newFile(self): #create a new function and remove all values in the QTEXTedit
self.textEdit.clear()
self.textEdit1.clear()
self.textEdit2.clear()
self.textEdit3.clear()
def openFile(self):
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
f = open(filename, 'r')
filedata = f.read()
self.textEdit1.setText(filedata)
self.textEdit2.setText(filedata)
self.textEdit3.setText(filedata)
f.close()
self.show()
def saveFile(self): # saving argument values in a filedata
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getSaveFileName(self, 'Save File', os.getenv('HOME'))
f = open(filename, 'w')
filedata = self.textEdit1.toPlainText()
f.write(filedata)
filedata = self.textEdit2.toPlainText()
f.write(filedata)
filedata = self.textEdit3.toPlainText()
f.write(filedata)
f.close()
def closeEvent(self, event):
reply = QtGui.QMessageBox.question(self, 'Message',
"Are you sure to quit?", QtGui.QMessageBox.Yes |
QtGui.QMessageBox.No, QtGui.QMessageBox.No)
if reply == QtGui.QMessageBox.Yes:
event.accept()
else:
event.ignore()
if __name__ == "__main__":
app = QtGui.QApplication(sys.argv)
window = MyApp()
window.show()
sys.exit(app.exec_())
if I understand your question properly, since you are writing textEdit values to a file in order, you'll need to read that values line by line when opening the file, instead of reading the whole file content using read() method. so the openFile() method should be something like this:
def openFile(self):
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getOpenFileName(self, 'Open File', os.getenv('HOME'))
count = 0
with open(filename,'r') as f:
for line in f:
count = count + 1
if count == 1 : self.textEdit1.setText(line)
elif count == 2 : self.textEdit2.setText(line)
elif count == 3 : self.textEdit3.setText(line)
else: break
self.show()
hope it helps!
UPDATE:
also change saveFile() method like below:
def saveFile(self): # saving argument values in a filedata
self.text = QtGui.QTextEdit(self)
filename = QtGui.QFileDialog.getSaveFileName(self, 'Save File', os.getenv('HOME'))
f = open(filename, 'w')
filedata = self.textEdit1.toPlainText()
filedata = str(filedata)+"\n"
f.write(filedata)
filedata = self.textEdit2.toPlainText()
filedata = str(filedata)+"\n"
f.write(filedata)
filedata = self.textEdit3.toPlainText()
filedata = str(filedata)+"\n"
f.write(filedata)
f.close()
I am using Scrapy to scrape a website but some of the characters, such as apostrophes, do not scrape correctly nor are they consistently the same wrong character, i.e., I've had an apostrophe show up as multiple odd characters in my result set. How do I ensure that all characters scrape properly?
Edit
I am trying to scrape http://www.nowtoronto.com/music/listings/ with the following scraper:
import urlparse
import time
from scrapy.http import Request
from scrapy.spider import BaseSpider
from scrapy.selector import Selector
#from NT.items import NowTorontoItem
from scrapy.item import Item, Field
class NowTorontoItem(Item):
eventArtist = Field()
eventTitle = Field()
eventHolder = Field()
eventDetails = Field()
#venueName = Field()
eventAddress = Field()
eventLocality = Field()
eventPostalCode = Field()
eventPhone = Field()
eventURL = Field()
eventPrice = Field()
eventDate = Field()
internalURL = Field()
class MySpider(BaseSpider):
name = "NTSpider"
allowed_domains = ["nowtoronto.com"]
start_urls = ["http://www.nowtoronto.com/music/listings/"]
def parse(self, response):
selector = Selector(response)
listings = selector.css("div.listing-item0, div.listing-item1")
for listing in listings:
item = NowTorontoItem()
for body in listing.css('span.listing-body > div.List-Body'):
item ["eventArtist"] = body.css("span.List-Name::text").extract()
item ["eventTitle"] = body.css("span.List-Body-Emphasis::text").extract()
item ["eventHolder"] = body.css("span.List-Body-Strong::text").extract()
item ["eventDetails"] = body.css("::text").extract()
#item ["internalURL"] = body.css("a::attr(href)").extract()
time.sleep(1)
for body in listing.css('div.listing-readmore'):
item ["internalURL"] = body.css("a::attr(href)").extract()
# yield a Request()
# so that scrapy enqueues a new page to fetch
detail_url = listing.css("div.listing-readmore > a::attr(href)")
if detail_url:
yield Request(urlparse.urljoin(response.url,
detail_url.extract()[0]),
meta={'item': item},
callback=self.parse_details)
else:
yield item
def parse_details(self, response):
self.log("parse_details: %r" % response.url)
selector = Selector(response)
listings = selector.css("div.whenwhereContent")
for listing in listings:
for body in listing.css('tr:nth-child(1) td.small-txt.dkgrey-txt.rightInfoTD'):
item = response.meta['item']
#item ["eventLocation"] = body.css("span[property='v:location']::text").extract()
#item ["eventOrganization"] = body.css("span[property='v:organization'] span[property='v:name']::text").extract()
#item ["venueName"] = body.css("span[property='v:name']::text").extract()
item ["eventAddress"] = body.css("span[property='v:street-address']::text").extract()
item ["eventLocality"] = body.css("span[property='v:locality']::text").extract()
item ["eventPostalCode"] = body.css("span[property='v:postal-code']::text").extract()
item ["eventPhone"] = body.css("span[property='v:tel']::text").extract()
item ["eventURL"] = body.css("span[property='v:url']::text").extract()
item ["eventPrice"] = listing.css('tr:nth-child(2) td.small-txt.dkgrey-txt.rightInfoTD::text').extract()
item ["eventDate"] = listing.css('span[content*="201"]::attr(content)').extract()
yield item
I am getting characters in some of the results like ée and é. These are supposed to be characters like é and ç.
Edit 2
I am not sure the issue is simply related to the file viewer I am using. When I open my first scrape in a text editor, an apostrophe is formatted as ’ whereas in my second scrape, the same apostrophe (from the same text string) is formatted as —È.
It turns out that the data is actually fine but the encoding was broken when I opened and saved the file in Excel. I have switched to Libre Office, which specifically asks for the encoding of the document when it is being opened, and everything works fine.
In my view i have a upload form:
<input type="file" name="file" value="search file" /><br />
In my controller I load it like that:
def file = request.getFile('file')
def f = file.getInputStream()
def input = f.getText()
So I have now a String called input with the content of the file.
I want it in UTF-8. How is this possible ?
Edit:
My problem is, that the file to be uploaded is in "Windows-1252" and German characters like äöü are different now in the string called "input".
If i convert the file with "Notepad++" in UTF-8 and then upload it, it works. But I cant do that every time.
Edit2:
def file = request.getFile('file') //get file from view
def File tmpfile = new File('C:/tmp/tmpfile.txt') //create temporary file
file.transferTo(tmpfile) //copy into tmpfile
CharsetToolkit toolkit = new CharsetToolkit(tmpfile) //toolkit with tmpfile
def charset = toolkit.getCharset() //save charset in a variable
def input = tmpfile.getText(charset) //get text with right charset
I tried this with a few different documents. But the variable charset is always UTF_8
You can use getText(String charset)
def input = f.getText('UTF-8')
I found a solution:
I used java-bib called jUniversalChardet and wrote the following method:
String getEncoding ( def inputstream ) {
def byte[] buf = new byte[4096]
def UniversalDetector detector = new UniversalDetector(null)
def nread
while ((nread = inputstream.read(buf)) > 0 && !detector.isDone()) {
detector.handleData(buf, 0, nread)
}
detector.dataEnd();
def encoding = detector.getDetectedCharset()
return encoding
}
In my code i have the following now:
def file = request.getFile('file')
def f = file.getInputStream()
def encoding = getEncoding(file.getInputStream())
def input = f.getText(encoding)
And it works :)
I have some data-scraping code intended to pull both the image url and the name of the image (located in the a tag). The code as its written looks like this:
BASE = 'http://antwrp.gsfc.nasa.gov/apod/'
f = open 'http://antwrp.gsfc.nasa.gov/apod/archivepix.html'
html_doc = Nokogiri::HTML(f.read)
html_doc.xpath('//b//a')[0..10].each do |element|
imgurl = BASE + element.attributes['href'].value
imgname = element.attributes['innerText']
puts imgname
doc = Nokogiri::HTML(open(imgurl).read)
doc.xpath('//p//a//img').each do |elem|
small_img = BASE + elem.attributes['src'].value
puts small_img
end
end
When I run that program I get this output:
http://antwrp.gsfc.nasa.gov/apod/image/1308/twolines_yen_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/perseids_vangaal_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/phas_jpl_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/m74_hubble_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/tafreshiIMG_4098Trail-s900.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/Albrechtsberg_Perseid2012-08-12_voltmer900.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/ngc3370_hst_900.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/auroraemeteors_boardman_1770.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/cone_noajgendler_960.jpg
http://antwrp.gsfc.nasa.gov/apod/image/1308/ioplus_galileo_960.jpg
The lines in between the links is where I expect the name of the image to appear (for example: "Moonset from Taiwan" for the first image). I have a feeling the reason I cannot get the name to appear is because it is a child node and I am not accessing it. Does anyone know how I should alter the imgname variable to return the image name?
What about
html_doc.xpath('//b//a')[0..10].each do |element|
imgurl = BASE + element.attributes['href'].value
#imgname = element.attributes['innerText']
imgname = element.content
puts imgname
...
end
element.text or element.inner_text should provide the same output in your case