Nice project!
Why don't you at least test-print self.raw and self.raw_read to see what you got.
bumsfeld 413 Nearly a Posting Virtuoso
You really should read at least one tutorial on OOP and classes.
bumsfeld 413 Nearly a Posting Virtuoso
It's best to test the module first with something like this:
from math import pow
from math import log10
def get_entropy(d, t):
"""
where d is the element's data dictionary and t is temperature
"""
t = t/1000.0
ent = (d['A']*log10(t) + d['B']*t + d['C']*pow(t,2.)/2. +
d['D']*pow(t,3.)/3. - d['E']/(2.*(pow(t,2.))) +
d['G'])/1000
return "%0.7f" % ent
# test the module
if __name__ == '__main__':
oxygen = {'A':31.32234, 'B':-20.23531, 'C':57.86644,
'D':-36.50624, 'E':-0.007374, 'F':-8.903471,
'G':246.7945, 'H':0.000000,
'EnthalpyTempZero':8.68,
'frequency':1580.19, 'EDFT':-4.9316435}
t = oxygen['EnthalpyTempZero']
entropy = get_entropy(oxygen, t)
print(entropy)
bumsfeld 413 Nearly a Posting Virtuoso
Eclipse is much too slow and too large, actually huge! Not really made for nimble Python programming.
bumsfeld 413 Nearly a Posting Virtuoso
PyGame isn't the only toolkit you can use for animation. If you use Python 3.1 and still wait for PyGame to be available, you can use Tinter for some simple animations:
# Tk_CanvasMove1.py
# explore Tkinter animation via canvas.move()
# Henri
import time
try:
# for Python2
import Tkinter as tk
except ImportError:
# for Python3
import tkinter as tk
root = tk.Tk()
root.title("canvas.move() test")
canvas = tk.Canvas(root, width=400, height=380)
canvas.pack()
# canvas.create_rectangle(x0, y0, x1, y1, option, ... )
# x0, y0, x1, y1 are corner coordinates of ulc to lrc diagonal
rc1 = canvas.create_rectangle(20, 260, 120, 360,
outline='white', fill='blue')
rc2 = canvas.create_rectangle(20, 10, 120, 110,
outline='white', fill='red')
# initial delay to view setting
canvas.update()
time.sleep(0.7)
for x in range(50):
y = x = 5
time.sleep(0.025)
# canvas.move(obj, xAmount, yAmount)
# objects are rectangles rc1 and rc2
canvas.move(rc1, x, -y)
canvas.move(rc2, x, y)
canvas.update()
time.sleep(0.7)
# reverse move
for x in range(50, 0, -1):
y = x = -5
time.sleep(0.025)
# canvas.move(obj, xAmount, yAmount)
# objects are rectangles rc1 and rc2
canvas.move(rc1, x, -y)
canvas.move(rc2, x, y)
canvas.update()
root.mainloop()
vegaseat commented: nicely done +13
Ene Uran commented: yes! +13
bumsfeld 413 Nearly a Posting Virtuoso
Put PyQT widgets on a color background using canvas:
# pqt_CanvasBackGround1.py
# use PyQT's paintEvent to create full frame canvas
# widgets will use the canvas as background
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyFrame(QWidget):
def __init__(self):
QWidget.__init__(self)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(100, 150, 350, 200)
self.setWindowTitle("paintEvent canvas as background")
# specify the canvas background color (r, g, b)
self.plum = QColor(221, 160, 221)
# create some regular widgets
# that will use the canvas as background
btn_red = QPushButton("Red")
btn_green = QPushButton("Green")
btn_blue = QPushButton("Blue")
# the label acts transparent, buttons do not
label = QLabel(" 1 \n 2 \n 3 \n 4 \n 5 \n 6 \n")
# use grid layout for the widgets
grid = QGridLayout()
# addWidget(widget, row, column, rowSpan=1, columnSpan=1)
grid.addWidget(btn_red, 0, 0, 1, 1)
grid.addWidget(btn_green, 0, 1, 1, 1)
grid.addWidget(btn_blue, 1, 0, 1, 1)
grid.addWidget(label, 2, 0, 1, 1)
self.setLayout(grid)
def paintEvent(self, event):
"""auto-create the painting canvas"""
painter = QPainter()
painter.begin(self)
# use brush for rectangle background
painter.setBrush(QBrush(self.plum))
# set recangle to full frame size
painter.drawRect(event.rect())
painter.end()
app = QApplication(sys.argv)
frame = MyFrame()
frame.show()
app.exec_()
vegaseat commented: great, I have been looking for colors +13
bumsfeld 413 Nearly a Posting Virtuoso
Look at PyQT's progress bar widget and simple timer to drive it:
# pqt_progressbar1.py
# explore PyQT's progress bar and simple timer widgets
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyFrame(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('QProgressBar')
self.pbar = QProgressBar(self)
self.pbar.setGeometry(30, 40, 200, 25)
self.button = QPushButton('Start', self)
self.button.setFocusPolicy(Qt.NoFocus)
# absolute positioning
self.button.move(40, 80)
self.connect(self.button, SIGNAL('clicked()'), self.onStart)
# QBasicTimer is simplified timer
# use QTimer for more options and control
self.timer = QBasicTimer()
self.step = 0;
def timerEvent(self, event):
"""preset method for timer widget"""
if self.step >= 100:
self.timer.stop()
return
self.step += 1
self.pbar.setValue(self.step)
def onStart(self):
"""toggle button action and label"""
if self.timer.isActive():
self.timer.stop()
self.button.setText('Start')
else:
# timer interval of 100 milliseconds
self.timer.start(100, self)
self.button.setText('Stop')
app = QApplication(sys.argv)
frame = MyFrame()
frame.show()
app.exec_()
bumsfeld 413 Nearly a Posting Virtuoso
Exampled code for PyQT's multiline text entry widget:
# pqt_TextEdit1.py
# explore PyQT's QTextEdit multiline text entry box
# click right mouse button in edit area for popup menu
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyFrame(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(100, 50, 300, 180)
self.setWindowTitle('QTextEdit() test')
self.edit = QTextEdit(self)
self.edit.append('just some text,\n you can append more')
self.edit.append('well, here is more!!!')
self.edit.append('click the right mouse button')
self.edit.append('to get option popup menu\n')
self.pbutton = QPushButton(self)
self.pbutton.setText(' transfer text to label ')
# label auto-adjusts to multiple lines
self.label = QLabel(self)
self.label.setText('label ...')
# use grid layout manager
grid = QGridLayout(self)
# addWidget(QWidget, row, column, rowSpan, columnSpan)
grid.addWidget(self.pbutton, 0, 0, 1, 1)
grid.addWidget(self.edit, 1, 0, 1, 2)
grid.addWidget(self.label, 2, 0, 1, 2)
self.setLayout(grid)
# bind the button clicked to action
self.connect(self.pbutton, SIGNAL("clicked()"), self.action)
def action(self):
# get the text from self.edit
text = self.edit.toPlainText()
# put the text into self.label
self.label.setText(text)
app = QApplication(sys.argv)
frame = MyFrame()
frame.show()
sys.exit(app.exec_())
bumsfeld 413 Nearly a Posting Virtuoso
I like wxPython. However, if you use the newer Python 3.1, it could take long time for wxPython to be available. So now I am learning PyQT.
Again, Tkinter isn't bad to learn in the beginning, just to get used to GUI programming concepts. To me PyGT is really complex, try to make listbox display and you see.
bumsfeld 413 Nearly a Posting Virtuoso
Sometimes it's nice to attach label to entry widget. One way to do this is with class object:
# pqt_EntryLab1.py
# create labeled data entry areas
# tested with Python 3.1 and PyQT 4.5
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyFrame(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(100, 150, 300, 150)
self.setWindowTitle('data entry with attached label')
# label to the 'left' side is default
self.e_name = LEditLab(self, "Enter your name:")
self.e_age = LEditLab(self, "Enter your age: ")
self.e_job = LEditLab(self, "Enter your job: ")
# display result 2 different ways, label on top
self.e_result2 = LEditLab(self, "Result: ", 'top')
self.e_result = EditLab(self, "Result:", 'top')
self.b_done = QPushButton("Done")
# use a grid layout to position the widgets
# note that the grid is centered on the frame
grid = QGridLayout(self)
# addWidget(QWidget, row, column, rowSpan, columnSpan)
grid.addWidget(self.e_name, 0, 0, 1, 3)
grid.addWidget(self.e_age, 1, 0, 1, 3)
grid.addWidget(self.e_job, 2, 0, 1, 3)
grid.addWidget(self.b_done, 3, 1, 1, 1)
grid.addWidget(self.e_result2, 4, 0, 1, 3)
grid.addWidget(self.e_result, 5, 0, 1, 3)
self.setLayout(grid)
# connect the button click signal to an action
self.connect(self.b_done, SIGNAL("clicked()"), self.action)
def action(self):
name = self.e_name.text()
age = self.e_age.text()
job = self.e_job.text()
s2 = "%s, %s, %s" % (name, age, job)
self.e_result2.setText(s2)
s = "%s\n%s\n%s\n" % (name, age, job)
self.e_result.setText(s)
class LEditLab(QWidget):
"""label QLineEdit data entry/display to the left or on top"""
def __init__(self, parent, mytext=QString(), pos='left'):
QWidget.__init__(self, parent)
self.label = QLabel(mytext)
self.edit = QLineEdit()
label_pos = QBoxLayout.LeftToRight if pos == …
bumsfeld 413 Nearly a Posting Virtuoso
Quick look at PyQT's QListWidget, commonly called 'list box'. Also shows how to create multiple buttons with the for loop. Here is short example:
# pqt_listbox2.py
# explore PyQT's QListWidget (list box) actions
# tested with Python 3.1 and PyQT 4.5
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyFrame(QWidget):
def __init__(self, coffee_list, parent=None):
QWidget.__init__(self, parent)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(100, 150, 420, 150)
self.setWindowTitle('Things to do with QListWidget')
self.coffee_list = coffee_list
self.listbox = QListWidget()
self.connect(self.listbox, SIGNAL("itemSelectionChanged()"),
self.on_select)
# use grid layout to position the widgets
grid = QGridLayout(self)
# addWidget(QWidget, row, column, rowSpan, columnSpan)
grid.addWidget(self.listbox, 0, 0, 7, 2)
# list of (btn_text, action_method) tuples
btn_action = [
("Load", self.lb_load),
("Sort", self.listbox.sortItems),
("Move Down", self.lb_down),
("Move Up", self.lb_up),
("Remove Line", self.lb_remove),
("Add Line", self.lb_add),
("Edit Line", self.lb_edit)]
# the standard button is the QPushButton widget
# create multiple buttons using the for loop
row = 0
for text, action in btn_action:
button = QPushButton(text)
grid.addWidget(button, row, 2, 1, 1)
self.connect(button, SIGNAL("clicked()"), action)
row += 1
self.setLayout(grid)
def lb_load(self):
"""list box load"""
# clear any existing data first
self.listbox.clear()
self.listbox.addItems(self.coffee_list)
# start with first line selected (highlighted)
self.listbox.setCurrentRow(0)
def lb_down(self):
"""move selected item down one list box line"""
row = self.listbox.currentRow()
if row < self.listbox.count() - 1:
item = self.listbox.takeItem(row)
self.listbox.insertItem(row + 1, item)
self.listbox.setCurrentItem(item)
def lb_up(self):
"""move selected item up one list box line"""
row = self.listbox.currentRow()
if row >= 1:
item = self.listbox.takeItem(row)
self.listbox.insertItem(row - 1, item)
self.listbox.setCurrentItem(item)
def lb_remove(self):
"""remove …
bumsfeld 413 Nearly a Posting Virtuoso
I have Python 3.1 installed in my XP machine and use PyScripter (Windows executable written with Delphi) or the Geany IDE.
For Python 2.5 I use Portable Python 2.5.4 that does not interfere with the installed Python 3.1 and that comes with the wonderful SPE IDE. SPE uses some great programs right from its tools, like WinPdb, Kiki, PyFilling, PyChecker, wxGlade, XRCed etc.
PyScripter from:
http://pyscripter.googlepages.com/
Portable Python from:
http://www.portablepython.com/releases/
bumsfeld 413 Nearly a Posting Virtuoso
Well you can say
Label(root,text="I'm a label!").grid(row = 0,column = 0)
so no, you don't have to.
Correct, but that gets to be messy too. I rather do my layouts in one spot, if there are lots of widgets.
bumsfeld 413 Nearly a Posting Virtuoso
Don't you need the label identifier for the layout manager?
You could go to three character identifier that is somewhat recognizable like 'emz' for email label or 'adz' for address label.
bumsfeld 413 Nearly a Posting Virtuoso
One nice graphical way to select calendar date is with the calendar widget. Here is the PyQT example:
# explore the PyQT QCalendarWidget widget
# tested with Python 3.1 and PyQT 4.5
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyCalendar(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 300, 280, 220)
self.setWindowTitle('Calendar')
self.calendar = QCalendarWidget(self)
self.calendar.setGridVisible(True)
# use absolute layout (x_pos, y_pos) for widgets
self.calendar.move(20, 20)
self.connect(self.calendar, SIGNAL('selectionChanged()'),
self.show_date)
self.label = QLabel(self)
self.label.move(120, 180)
self.label2 = QLabel(self)
self.label2.setGeometry(85, 200, 150, 20)
# show initial date
self.show_date()
def show_date(self):
date = self.calendar.selectedDate()
# to get month/day/year like '8/13/2009' use ...
s = "%s/%s/%s" % (date.month(), date.day(), date.year())
self.setWindowTitle(s) # test
# date.toPyDate() gives year-month-day like '2009-8-13'
self.label.setText(str(date.toPyDate()))
# or you can use Qdate formatted string
# to show something like 'Thursday August 13 2009'
s2 = date.toString('dddd MMMM d yyyy')
self.label2.setText(s2)
app = QApplication(sys.argv)
mc = MyCalendar()
mc.show()
app.exec_()
bumsfeld 413 Nearly a Posting Virtuoso
Python31 is joy, here I am exploring named tuples and ordered dictionaries and their interconnection:
# some play with named tuples and ordered dictionaries
# needs Python3
import collections as co
# set up named tuple where staff is the identifier
# and the field names are fname, sname, age
ntup = co.namedtuple('staff', 'fname, sname, age')
# load the tuple
nt1 = ntup('Hank', 'Zoller', 27)
nt2 = ntup('Bjorn', 'Bartok', 34)
# this would give an error, not enough args
#nt3 = ntup('Jack', 'Schiett')
# show the named tuple
print(nt1) # staff(fname='Hank', sname='Zoller', age=27)
print(nt2) # staff(fname='Bjorn', sname='Bartok', age=34)
print(nt2.fname) # Bjorn
print(nt2.age) # 34
# show the field names
print(nt1._fields) # ('fname', 'sname', 'age')
# replace/update items by field name
nt4 = nt1._replace(sname='Zeller', age=28)
print(nt1) # staff(fname='Hank', sname='Zoller', age=27)
print(nt4) # staff(fname='Hank', sname='Zeller', age=28)
# convert to ordered dictionary
odict = nt2._asdict()
print(odict)
# convert ordered dictionary to regular dictionary
print(dict(odict))
# pop the last item
odict.popitem()
print(odict)
print(odict['sname'])
"""my output -->
OrderedDict([('fname', 'Bjorn'), ('sname', 'Bartok'), ('age', 34)])
{'age': 34, 'sname': 'Bartok', 'fname': 'Bjorn'}
OrderedDict([('fname', 'Bjorn'), ('sname', 'Bartok')])
Bartok
"""
# convert dictionary to named tuple
d = {'age': 34, 'sname': 'Bartok', 'fname': 'Bjorn'}
nt5 = ntup(**d)
print(nt5) # staff(fname='Bjorn', sname='Bartok', age=34)
bumsfeld 413 Nearly a Posting Virtuoso
Function raw_input() would force the user to type in the entire XML code. I don't think you want this.
Normally the XML code would come from file, something like this:
fin = open("Myxml.xml", "r")
xml_string = fin.read()
fin.close()
# now the xml code is represented by xml_string for you to work on.
bumsfeld 413 Nearly a Posting Virtuoso
For now, I am working on:
s=raw_input("Enter a number to simplify: ") global p p=0 def loop(): for i in s: p+=int(i) if(p>9): loop() return p print(p)
You got the right idea, but if you insist on recursion, you have to follow certain rules:
#s=raw_input("Enter a number to simplify: ")
s = '123456789' # for test
def loop(s, p=0):
for i in s:
p += int(i)
if p > 9:
# recursively loop with adjusted string s
return loop(str(p))
return p
n = loop(s)
print(n) # 9
bumsfeld 413 Nearly a Posting Virtuoso
You can give your wxPython window nice custom icon:
# experiment with wxPython's wx.Icon() and SetIcon()
import wx
class MyFrame(wx.Frame):
"""make a frame, inherits wx.Frame"""
def __init__(self):
wx.Frame.__init__(self, None, -1, 'wxPython custom icon',
pos=wx.Point(300, 150), size=wx.Size(300, 350))
self.SetBackgroundColour('green')
# pick icon file (.ico) you have ...
#iconFile = "py.ico"
# or 32x32 Windows .bmp file will do ...
# (will miss mask if not rectangular image)
icon_file = "Attention32x32.bmp"
self.SetIcon(wx.Icon(icon_file, wx.BITMAP_TYPE_ICO))
# show the frame
self.Show(True)
application = wx.App(0)
# call class MyFrame
window = MyFrame()
application.MainLoop()
bumsfeld 413 Nearly a Posting Virtuoso
You can use 32x32 Windows .bmp file instead of .ico file.
bumsfeld 413 Nearly a Posting Virtuoso
Hint, in while loop turn the number string into list of individual digits and sum the list until the sum is less than 10, then break.
Careful here, you are using strings(characters) and integers. So you have to use str() and int() to convert at the appropriate time.
For example:
s = '123'
print list(s) # ['1', '2', '3']
# for sum() you want list of integers
print [int(x) for x in s] # [1, 2, 3]
print sum([int(x) for x in s]) # 6
bumsfeld 413 Nearly a Posting Virtuoso
Maybe something like wx.ScrolledWindow will do, see:
http://www.daniweb.com/forums/showpost.php?p=933440&postcount=116
bumsfeld 413 Nearly a Posting Virtuoso
Example of wx.ScrolledWindow to display large area in one small frame:
# test wx.ScrolledWindow(parent, id, pos, size, style)
# with multiple widgets that exceed normal frame area
# tested with Python 2.5.4 and wxPython 2.8.9.1
# Henri
import wx
class MyFrame(wx.Frame):
def __init__(self, parent, mytitle):
wx.Frame.__init__(self, parent, -1, mytitle, size=(400,300))
# create scrolled window
# let the wx.ScrolledWindow fill the frame
self.scrollw = wx.ScrolledWindow(self, wx.ID_ANY)
self.scrollw.SetBackgroundColour('green')
# set EnableScrolling(bool x_scrolling, bool y_scrolling)
# default is self.scrollw.EnableScrolling(True, True)
# if True, wx.ScrolledWindow shows its scroll bars
# create the scroll bars, set the scrolling ranges (pixels)
max_w = 1000
max_h = 1000
# SetScrollbars(pixelsPerUnitX, pixelsPerUnitY, noUnitsX,
# noUnitsY)
self.scrollw.SetScrollbars(20, 20, max_w//20, max_h//20)
# pick something that needs area larger than the frame
self.createMultiLabels()
def createMultiLabels(self):
"""from one of vegaseat's example codes"""
# things to put on the labels
label_string = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ->UM'
# wx.GridSizer(rows, cols, vgap, hgap)
gsizer = wx.GridSizer(6, 5, 0, 0)
# create list of labels
# acccess with self.labels[0], self.labels[1] etc.
self.labels = []
for c in label_string:
# labels have of scroll window as parent
self.labels.append(wx.StaticText(self.scrollw, -1,
label=c, style=wx.ALIGN_CENTRE|wx.SUNKEN_BORDER))
# iterate through the list of labels and set
# layout, optionally font and colour
font = wx.Font(60, wx.MODERN, wx.NORMAL, wx.BOLD)
for x in self.labels:
x.SetFont(font)
x.SetBackgroundColour("yellow")
gsizer.Add(x, 0, flag=wx.ALL, border=20)
# set the sizer in scroll window
self.scrollw.SetSizer(gsizer)
app = wx.App(0)
# create MyFrame instance and show the frame
MyFrame(None, "wx.ScrolledWindow for large display").Show()
app.MainLoop()
bumsfeld 413 Nearly a Posting Virtuoso
One more simple way to present data in table form:
# use PyQT's QTableWidget, QTableWidgetItem and setItem
# to show data in simple table format
# tested with Python 3.1 and PyQT 4.5
# Henri
import sys
# simplified import
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyTable(QTableWidget):
def __init__(self, data, rows, cols):
QTableWidget.__init__(self, rows, cols)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 200, 280, 180)
self.setWindowTitle("Simple QTableWidget")
self.data = data
self.set_data()
def set_data(self):
"""self.data is list of (fname, sname, age) tuples"""
row = 0
for tup in self.data:
col = 0
for item in tup:
newitem = QTableWidgetItem(item)
self.setItem(row, col, newitem)
col += 1
row += 1
# fname, sname, age raw data for instance from file
staff = """\
Frank, Marco, 27
Henri, Poulong, 34
Gisela, Lang, 19
Lance, Handy, 46"""
# create list of (fname, sname, age) tuples
data = []
for line in staff.split('\n'):
fname, sname, age = line.split(',')
data.append((fname.strip(), sname.strip(), age.strip()))
app = QApplication(sys.argv)
rows = 5
cols = 3
table = MyTable(data, rows, cols)
table.show()
sys.exit(app.exec_())
bumsfeld 413 Nearly a Posting Virtuoso
Now I see, you want to avoid flood of email from DaniWeb.
You can:
1 Follow jlm699 advice
2 Try your Python skills and write small program to UNsubscribe you. :)
bumsfeld 413 Nearly a Posting Virtuoso
Exploring PyQT's QListView and QAbstractListModel. This little code pops up posssible words from word list as you type:
# using PyQT's QListView and QAbstractListModel
# to match partially typed word to words in list
# make matching case insensitive
# tested with Python 3.1 and PyQT 4.5
# Henri
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyWindow(QWidget):
def __init__(self, words, *args):
QWidget.__init__(self, *args)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 300, 320, 250)
self.setWindowTitle("Match words with PyQT's QListView")
self.words = words
# create objects
self.label = QLabel("Start typing to match words in list:")
#self.edit = MyLineEdit()
self.edit = QLineEdit()
self.lmodel = MyListModel(self, self.words)
self.lview = QListView()
self.lview.setModel(self.lmodel)
# layout
layout = QVBoxLayout()
layout.addWidget(self.label)
layout.addWidget(self.edit)
layout.addWidget(self.lview)
self.setLayout(layout)
# one key has been pressed in edit
self.connect(self.edit, SIGNAL("textChanged(QString)"),
self.update)
def update(self):
"""
updates the list of possible completions each time key
is pressed, use lower() to make things case insensitive
"""
p = str(self.edit.text()).lower()
new_list = [w for w in self.words if w.lower().find(p)==0]
self.lmodel.setAllData(new_list)
class MyListModel(QAbstractListModel):
def __init__(self, parent, words, *args):
"""
words is list of words
"""
QAbstractListModel.__init__(self, parent, *args)
self.words = words
def rowCount(self, parent=QModelIndex()):
return len(self.words)
def data(self, index, role):
if index.isValid() and role == Qt.DisplayRole:
return QVariant(self.words[index.row()])
else:
return QVariant()
def setAllData(self, new_list):
"""replace old list with new list"""
self.words = new_list
self.reset()
# this is just test list of words
state_list = [
'Mississippi', 'Oklahoma', 'Delaware', 'Minnesota',
'Arkansas', 'New Mexico', 'Indiana', 'Louisiana',
'Texas', 'Wisconsin', 'Kansas', 'Connecticut',
'California', 'West Virginia', 'Georgia', 'North Dakota',
'Pennsylvania', …
bumsfeld 413 Nearly a Posting Virtuoso
Presenting data in the form of a table that can be sorted by column is slick, and relatively easy to do with PyQT's QTableView widget:
# use PyQT's QTableView and QAbstractTableModel
# to present tabular data (with column sort option)
# tested with Python 3.1 and PyQT 4.5
# Henri
import operator
import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyWindow(QWidget):
def __init__(self, element_list, header, *args):
QWidget.__init__(self, *args)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 200, 460, 300)
self.setWindowTitle("Sorting PyQT's QTableView")
self.header = header
self.mydata = element_list
# create table
table = self.createTable()
# use vbox layout
layout = QVBoxLayout()
layout.addWidget(table)
self.setLayout(layout)
def createTable(self):
# create table view
tview = QTableView()
# set table model
tmodel = MyTableModel(self, self.mydata, self.header)
tview.setModel(tmodel)
# set minimum size of table
tview.setMinimumSize(450, 300)
# hide grid
tview.setShowGrid(False)
# set font
font = QFont("Courier New", 8)
tview.setFont(font)
# hide vertical header
vh = tview.verticalHeader()
vh.setVisible(False)
# set horizontal header properties
hh = tview.horizontalHeader()
hh.setStretchLastSection(True)
# set column width to fit contents
tview.resizeColumnsToContents()
# set all row heights
nrows = len(self.mydata)
for row in range(nrows):
tview.setRowHeight(row, 18)
# enable sorting
tview.setSortingEnabled(True)
return tview
class MyTableModel(QAbstractTableModel):
def __init__(self, parent, mydata, header, *args):
"""
mydata is list of tuples
header is list of strings
tuple length has to match header length
"""
QAbstractTableModel.__init__(self, parent, *args)
self.mydata = mydata
self.header = header
def rowCount(self, parent):
return len(self.mydata)
def columnCount(self, parent):
return len(self.mydata[0])
def data(self, index, role):
if not index.isValid():
return QVariant()
elif role != Qt.DisplayRole:
return …
bumsfeld 413 Nearly a Posting Virtuoso
The wxPython wx.lib.fancytext.StaticFancyText() class can display colorful text written in XML format:
# wxPython's
# wx.lib.fancytext.StaticFancyText(parent, id, text, ...)
# can display text written in XML format
# Henri
import wx
import wx.lib.fancytext as wxft
class FancyText(wx.Panel):
def __init__(self, parent, xml_text):
wx.Panel.__init__(self, parent, -1)
self.ftext = wxft.StaticFancyText(self, -1, text=xml_text,
background=wx.Brush('black'))
red = '<font family="swiss" color="red" size="48">'
blue = '<font family="swiss" color="blue" size="48">'
green = '<font family="swiss" color="green" size="48">'
# match the 3 <font ...> tags with closing </font> tags
xml_text = """\
%s Feeling %sblue?
%s Or green with envy?
</font>
</font>
</font>
""" % (red, blue, green)
app = wx.App(0)
mytitle = 'wx.lib.fancytext.StaticFancyText()'
mysize = (620, 220)
frame = wx.Frame(None, -1, title=mytitle, size=mysize)
FancyText(frame, xml_text)
frame.Show()
app.MainLoop()
bumsfeld 413 Nearly a Posting Virtuoso
Check into:
wx.lib.filebrowsebutton.FileBrowseButton(parent, labelText, fileMask)
bumsfeld 413 Nearly a Posting Virtuoso
Note that module os calls do not allow your Python program
to run in the background, whereas module subprocess calls do.
bumsfeld 413 Nearly a Posting Virtuoso
Let's hope the file _cpyHook.pyd was compiled with the proper MS C version to match the Python2.6 exe file.
bumsfeld 413 Nearly a Posting Virtuoso
i know that 6/5 returns 1
and 6/5.0 returns 1.2
but suppose i am defining n=6 and d=5, i want n/d to return 1.2 instead of 1, how do i do it?
With Python3 things have changed. Floating point division is now '/' and integer division '//'.
print(6/5) # 1.2
print(6//5) # 1
bumsfeld 413 Nearly a Posting Virtuoso
Replying to your second question:
l=['apple','orange','mango','pear','strawberry'] for a in l: if(l=='pear'): l.remove(i)
That ought to work! :P
Why not simpply:
mylist = ['apple','orange','mango','pear','strawberry']
mylist.remove('pear')
print(mylist) # ['apple', 'orange', 'mango', 'strawberry']
bumsfeld 413 Nearly a Posting Virtuoso
Another look at PyQT's canvas:
# pqt_drawtext2.py
# playing with PyQT's QPainter
# setPen, setBrush, setFont, drawRect and drawText
import sys
# simpler import
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class DrawText(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(300, 300, 350, 150)
self.setWindowTitle("Playing with PyQT's QPainter")
def paintEvent(self, event):
painter = QPainter()
painter.begin(self)
# PyQT has some color constants available
# give the canvas blue background color
painter.setBrush(QBrush(QColor("navy")))
painter.drawRect(event.rect())
# this will be the text color
painter.setPen(QColor("orange"))
# check the fonts available on your computer
# for instance in C:\WINDOWS\Fonts
painter.setFont(QFont('Comic Sans MS', 32))
# drawText (x, y, QString s)
painter.drawText(45, 90, "Hello World")
painter.end()
app = QApplication(sys.argv)
dt = DrawText()
dt.show()
app.exec_()
bumsfeld 413 Nearly a Posting Virtuoso
The Open Graphics Library (OGL) is now well integrated with wxPython, but to go from there to something that works like VPython you need lots of work:
import wx
import wx.lib.ogl as ogl
class MyFrame(wx.Frame):
def __init__(self):
wx.Frame.__init__( self, None, wx.ID_ANY,
title="explore wx.lib.ogl", size=(400,300))
canvas = ogl.ShapeCanvas(self)
canvas.SetBackgroundColour("yellow")
diagram = ogl.Diagram()
# marry the two ...
canvas.SetDiagram(diagram)
diagram.SetCanvas(canvas)
# create some standard shapes ...
# (check how creation order affects overlap)
circle = ogl.CircleShape(100.0) # radius
circle.SetX(75.0) # center x
circle.SetY(75.0)
circle.SetPen(wx.RED_PEN)
circle.SetBrush(wx.CYAN_BRUSH)
canvas.AddShape(circle)
text = ogl.TextShape(250, 30) # (w, h)
text.SetX(180) # center x
text.SetY(240)
text.AddText("you can drag the circle or the text")
canvas.AddShape(text)
diagram.ShowAll(True)
# use v box sizer
sizer = wx.BoxSizer(wx.VERTICAL)
# canvas will grow as frame is stretched
sizer.Add(canvas, 1, wx.GROW)
self.SetSizer(sizer)
app = wx.App()
ogl.OGLInitialize()
MyFrame().Show()
app.MainLoop()
bumsfeld 413 Nearly a Posting Virtuoso
Looking at PyQT's grid layout manager:
# pqt_gridlayout1.py
# start of small calculator
import sys
# simple general import
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class GridLayout(QWidget):
def __init__(self, parent=None):
QWidget.__init__(self, parent)
self.setWindowTitle('grid layout')
bt_names = ['Cls', 'Bck', '', 'Close',
'7', '8', '9', '/',
'4', '5', '6', '*',
'1', '2', '3', '-',
'0', '.', '=', '+']
grid = QGridLayout()
pos = [(0, 0), (0, 1), (0, 2), (0, 3),
(1, 0), (1, 1), (1, 2), (1, 3),
(2, 0), (2, 1), (2, 2), (2, 3),
(3, 0), (3, 1), (3, 2), (3, 3 ),
(4, 0), (4, 1), (4, 2), (4, 3)]
j = 0
for b in bt_names:
button = QPushButton(b)
if j == 2:
# addWidget(QWidget, row, column, rowSpan, columnSpan)
grid.addWidget(QLabel(''), 0, 2)
else: grid.addWidget(button, pos[j][0], pos[j][1])
j = j + 1
self.setLayout(grid)
app = QApplication(sys.argv)
qb = GridLayout()
qb.show()
sys.exit(app.exec_())
bumsfeld 413 Nearly a Posting Virtuoso
I have Python2.5.4 and Python3.1 working on the same XP machine.
Programming editors (IDE) like IDLE may have to be convinced with batch file to use the correct Python version.
Here is example:
REM batch file to force IDLE to run with Python 3.1
REM save as IDLE31.bat
C:\Python31\Pythonw.exe -u C:\Python31\Lib\idlelib\idle.pyw
One similar batch file needs to be created for Python25.
bumsfeld 413 Nearly a Posting Virtuoso
For the somewhat simple program you are writing, you don't need class objects. Those things are not too enjoyable for beginners. With Java you would be stuck with them, but Python offers you the freedom to do procedural programming too. Each room would get one name/identifier like this:
room1 = """\
You are standing in a restroom. There is a doorway to the north,
the east, west, and south walls have human-sized holes blown into them.
"""
# display the room description for room1
print(room1)
You can set up descriptions for room2, room3 and so on.
bumsfeld 413 Nearly a Posting Virtuoso
For some odd reason that question has come up and has been solved several times in the past. One quick search will certainly help you.
bumsfeld 413 Nearly a Posting Virtuoso
The PyQT GUI toolkit's QLabel widget can actually display HTML formatted text directly. This allows for relatively easy formatting of text:
# PyQT's QLabel widget can display html formatted text
import sys
# use this import option for simplicity
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyForm(QWidget):
def __init__(self, html_text):
QWidget.__init__(self)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(100, 150, 320, 100)
self.setWindowTitle("html formatted text")
self.label = QLabel(html_text)
# use grid layout
grid = QGridLayout()
# addWidget(widget, row, column, rowSpan=1, columnSpan=1)
grid.addWidget(self.label, 0, 0)
self.setLayout(grid)
# color is in hex format "#RRGGBB"
html_text = """\
<font face="Times New Roman" size=7 color="#0000FF">
Example of <b>bold</b> html formatted text in blue
</font>
"""
app = QApplication(sys.argv)
form = MyForm(html_text)
form.show()
app.exec_()
bumsfeld 413 Nearly a Posting Virtuoso
Only potential problem with place() is, that it does not resize with window.
bumsfeld 413 Nearly a Posting Virtuoso
Similar to the PyQT GUI example above, the Thinter GUI toolkit also has input dialogs that validate the input:
# Python GUI toolkit Tkinter has 3 different data input dialogs:
# tkSimpleDialog.askstring(title, prompt [,options])
# tkSimpleDialog.askinteger(title, prompt [,options])
# tkSimpleDialog.askfloat(title, prompt [,options])
# does error trapping with int and float, also optional max/min
# there is also an initialvalue=parameter
try:
# for Python2
import Tkinter as tk
import tkSimpleDialog as tksd
except ImportError:
# for Python3
import tkinter as tk
import tkinter.simpledialog as tksd
root = tk.Tk()
# parent=root needed to put dialog window on top of parent root window
mystr = tksd.askstring("Dialog (String)", "Enter your name:", parent=root)
print(mystr)
age = tksd.askinteger("Dialog (Integer)", "Enter your age:", parent=root,
minvalue=0, maxvalue=120)
print(age)
pay = tksd.askfloat("Dialog (Float)", "Enter your annual pay:",
parent=root, minvalue=1000)
print(pay)
root.mainloop()
# optional help
help(tksd)
bumsfeld 413 Nearly a Posting Virtuoso
The Tkinter GUI toolkit has data input dialogs that will validate your input, as shown here:
# Python GUI toolkit Tkinter has three different data input dialogs:
# tkSimpleDialog.askstring(title, prompt [,options])
# tkSimpleDialog.askinteger(title, prompt [,options])
# tkSimpleDialog.askfloat(title, prompt [,options])
# does error trapping with int and float, also optional max/min
# there is also an initialvalue=parameter
try:
# for Python2
import Tkinter as tk
import tkSimpleDialog as tksd
except:
# for Python3
import tkinter as tk
import tkinter.simpledialog as tksd
root = tk.Tk()
# parent=root needed to put dialog window on top of parent root window
mystr = tksd.askstring("Dialog (String)", "Enter your name:", parent=root)
print(mystr)
age = tksd.askinteger("Dialog (Integer)", "Enter your age:", parent=root,
minvalue=0, maxvalue=120)
print(age)
pay = tksd.askfloat("Dialog (Float)", "Enter your annual pay:",
parent=root, minvalue=1000)
print(pay)
root.mainloop()
# optional help
#help(tksd)
bumsfeld 413 Nearly a Posting Virtuoso
Yes, instead of using geometry manager pack() or grid(), use place(x, y) for layouts. Note that place(x, y) is absolute, and coordinates x or y can go negative to shift the widget out off the window. One nice trick!
Care should be taken not to mix the different geometry managers!!!
bumsfeld 413 Nearly a Posting Virtuoso
You have to convert your data string to list of lists and then sort the sublists by item index:
s = """\
27 4 220 16 0.76151102 1.06059456
27 4 220 17 0.61465055 0.90107796
27 4 221 22 0.81186094 1.12214581
27 4 223 28 0.69887889 0.98993400
27 4 225 30 0.74796748 1.04485376"""
# create list of lists from the data string
mylist = []
for line in s.splitlines():
temp_list = []
for item in line.split():
temp_list.append(eval(item))
mylist.append(temp_list)
print("Original lists:")
for sublist in mylist:
print(sublist)
print('-'*40)
print("Sorted by the 5th item:")
# inplace sort by the 5th item which is at index 4
ix = 4
mylist.sort(key=lambda x: x[ix])
for sublist in mylist:
print(sublist)
"""result=
Original lists:
[27, 4, 220, 16, 0.76151102, 1.06059456]
[27, 4, 220, 17, 0.61465055, 0.90107796]
[27, 4, 221, 22, 0.81186094, 1.12214581]
[27, 4, 223, 28, 0.69887889, 0.989934]
[27, 4, 225, 30, 0.74796748, 1.04485376]
----------------------------------------
Sorted by the 5th item:
[27, 4, 220, 17, 0.61465055, 0.90107796]
[27, 4, 223, 28, 0.69887889, 0.989934]
[27, 4, 225, 30, 0.74796748, 1.04485376]
[27, 4, 220, 16, 0.76151102, 1.06059456]
[27, 4, 221, 22, 0.81186094, 1.12214581]
"""
bumsfeld 413 Nearly a Posting Virtuoso
hi all. I know that when you create a class, you put all arguements for that class in a __init__ functions, but what about for actaully making classes? confused? this is what I mean:
class Aclass(Object): insert code here...
what is the purpose of 'Object'?
This is the newer class writing style and it inherits the built-in 'object' (note that Python is case sensitive!). 'object' contains some rudimentary things for the class.
Use:
print(dir(object))
to look at those.
Here is one of the differences between old and new style class:
class Oldstyle:
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
print(self.__dict__) # {'a': 1, 'c': 3, 'b': 2}
class Newstyle(object):
"""
__slots__ prevents new variable creation outside the class
and improves the speed by replacing the usual class __dict__
"""
# 'register' the variables allowed
__slots__ = ["a", "b", "c"]
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
#print(self.__dict__) # will give error
oldobj = Oldstyle()
oldobj.d = 4 # no error
newobj = Newstyle()
newobj.d = 4 # gives error, since d is not 'registered'
bumsfeld 413 Nearly a Posting Virtuoso
You can use this:
mylist = [
[1, 9, 22, 28, 0.69887889000000003, 0.98993399999999998, 2],
[4, 27, 6, 22, 0.81186093999999998, 1.1221458099999999, 2],
[4, 27, 100, 30, 0.74796748000000002, 1.0448537600000001, 2],
[4, 1, 30, 45, 0.48522300000000002, 0.77061900999999999, 2],
[4, 27, 1, 51, 0.54467741999999997, 0.83013524999999999, 2],
[4, 28, 22, 4, 0.77556899999999995, 1.0917697900000001, 2],
[5, 27, 22, 50, 0.81594683999999995, 1.1273952, 2],
[6, 27, 22, 31, 0.91040723999999995, 1.26681591, 2],
[7, 108, 22, 53, 0.69060584999999997, 0.98095147999999999,2],
[8, 27, 22, 46, 0.94473684000000002, 1.33349425, 2]]
# inplace sort by the 4th item which is at index 3
ix = 3
mylist.sort(key=lambda x: x[ix])
for item in mylist:
print(item)
""" result =
[4, 28, 22, 4, 0.775569, 1.09176979, 2]
[4, 27, 6, 22, 0.81186094, 1.12214581, 2]
[1, 9, 22, 28, 0.69887889, 0.989934, 2]
[4, 27, 100, 30, 0.74796748, 1.04485376, 2]
[6, 27, 22, 31, 0.91040724, 1.26681591, 2]
[4, 1, 30, 45, 0.485223, 0.77061901, 2]
[8, 27, 22, 46, 0.94473684, 1.33349425, 2]
[5, 27, 22, 50, 0.81594684, 1.1273952, 2]
[4, 27, 1, 51, 0.54467742, 0.83013525, 2]
[7, 108, 22, 53, 0.69060585, 0.98095148, 2]
"""
bumsfeld 413 Nearly a Posting Virtuoso
Just bought used Dell XP notebook for class work and installed Python 3.1 and then PyQT4 form:
http://www.riverbankcomputing.co.uk/software/pyqt/download
Windows installer (14JUL2009):
PyQt-Py3.1-gpl-4.5.2-1.exe
I also installed PyScripter IDE from:
http://code.google.com/p/pyscripter/
Windows installer:
PyScripter-v1.9.9.7-Setup.exe
All Python things works charmingly well!
Here is my experiment with the PyQT code:
# simple PyQT window with two buttons and one label
# to test pop-up dialogs for getting name and age
# QInputDialog.getText(parent, title, label, echo=QLineEdit.Normal,
# text=QString(), flags=0)
# QInputDialog.getInt(parent, title, label, value, minValue,
# maxValue, step=1, flags=0)
# http://www.riverbankcomputing.com/static/Docs/PyQt4/html/qinputdialog.html
import sys
# use this import option for simplicity
from PyQt4.QtCore import *
from PyQt4.QtGui import *
class MyForm(QWidget):
def __init__(self):
QWidget.__init__(self)
# setGeometry(x_pos, y_pos, width, height)
self.setGeometry(100, 150, 320, 100)
self.setWindowTitle("Testing dialog input")
self.name = ""
btn_name = QPushButton("Get Name")
self.connect(btn_name, SIGNAL("clicked()"), self.get_name)
btn_age = QPushButton("Get Age")
# bind the button click to a function reference
self.connect(btn_age, SIGNAL("clicked()"), self.get_age)
self.label = QLabel("------------------")
# use grid layout for the widgets
grid = QGridLayout()
# addWidget(widget, row, column, rowSpan=1, columnSpan=1)
grid.addWidget(btn_name, 0, 0)
grid.addWidget(btn_age, 1, 0)
# this will span the label over 3 columns
grid.addWidget(self.label, 2, 0, 1, 3)
self.setLayout(grid)
def get_name(self):
self.name, ok = QInputDialog.getText(self,
self.tr("Name"),
self.tr("Enter your name:"))
self.show_result(ok)
def get_age(self):
# initial age 0, limit between 1 and 120
self.age, ok = QInputDialog.getInteger(self,
self.tr("Age"),
self.tr("Enter your age:"),
0, 1, 120)
self.show_result(ok)
def show_result(self, ok):
if ok and self.name and str(self.age):
s = "%s you are %s old" …
bumsfeld 413 Nearly a Posting Virtuoso
Win32 Extensions for Python from:
http://starship.python.net/crew/mhammond/win32/Downloads.html
is available in it's Python3 version, see:
http://sourceforge.net/project/showfiles.php?group_id=78018
and download and install:
pywin32-213.win32-py3.0.exe
bumsfeld 413 Nearly a Posting Virtuoso
To follow up on the paulthom12345 information:
"""
win32api.GetVolumeInformation(path)
returns tuple containing ...
string - name of volume/disk/drive
long - serial number of volume/disk/drive
long - maximum component length of a file name
long - flags specific to the file system
string - file system name
"""
import win32api
path = "C:/"
info = win32api.GetVolumeInformation(path)
print( "disk serial number = %d" % info[1] )
"""
my output on Vista machine -->
disk serial number = 1022625589
"""