Python GUI Programming

Reply   View First Unread View First Unread

Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #31
Jul 25th, 2009
Another look at PyQT's canvas:
  1. # pqt_drawtext2.py
  2. # playing with PyQT's QPainter
  3. # setPen, setBrush, setFont, drawRect and drawText
  4.  
  5. import sys
  6. # simpler import
  7. from PyQt4.QtCore import *
  8. from PyQt4.QtGui import *
  9.  
  10. class DrawText(QWidget):
  11. def __init__(self, parent=None):
  12. QWidget.__init__(self, parent)
  13. # setGeometry(x_pos, y_pos, width, height)
  14. self.setGeometry(300, 300, 350, 150)
  15. self.setWindowTitle("Playing with PyQT's QPainter")
  16.  
  17. def paintEvent(self, event):
  18. painter = QPainter()
  19. painter.begin(self)
  20. # PyQT has some color constants available
  21. # give the canvas blue background color
  22. painter.setBrush(QBrush(QColor("navy")))
  23. painter.drawRect(event.rect())
  24. # this will be the text color
  25. painter.setPen(QColor("orange"))
  26. # check the fonts available on your computer
  27. # for instance in C:\WINDOWS\Fonts
  28. painter.setFont(QFont('Comic Sans MS', 32))
  29. # drawText (x, y, QString s)
  30. painter.drawText(45, 90, "Hello World")
  31. painter.end()
  32.  
  33.  
  34. app = QApplication(sys.argv)
  35. dt = DrawText()
  36. dt.show()
  37. app.exec_()
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #32
Jul 27th, 2009
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:
  1. # use PyQT's QTableView and QAbstractTableModel
  2. # to present tabular data (with column sort option)
  3. # tested with Python 3.1 and PyQT 4.5
  4. # Henri
  5.  
  6. import operator
  7. import sys
  8. from PyQt4.QtCore import *
  9. from PyQt4.QtGui import *
  10.  
  11. class MyWindow(QWidget):
  12. def __init__(self, element_list, header, *args):
  13. QWidget.__init__(self, *args)
  14. # setGeometry(x_pos, y_pos, width, height)
  15. self.setGeometry(300, 200, 460, 300)
  16. self.setWindowTitle("Sorting PyQT's QTableView")
  17.  
  18. self.header = header
  19. self.mydata = element_list
  20. # create table
  21. table = self.createTable()
  22.  
  23. # use vbox layout
  24. layout = QVBoxLayout()
  25. layout.addWidget(table)
  26. self.setLayout(layout)
  27.  
  28. def createTable(self):
  29. # create table view
  30. tview = QTableView()
  31. # set table model
  32. tmodel = MyTableModel(self, self.mydata, self.header)
  33. tview.setModel(tmodel)
  34. # set minimum size of table
  35. tview.setMinimumSize(450, 300)
  36. # hide grid
  37. tview.setShowGrid(False)
  38. # set font
  39. font = QFont("Courier New", 8)
  40. tview.setFont(font)
  41. # hide vertical header
  42. vh = tview.verticalHeader()
  43. vh.setVisible(False)
  44. # set horizontal header properties
  45. hh = tview.horizontalHeader()
  46. hh.setStretchLastSection(True)
  47. # set column width to fit contents
  48. tview.resizeColumnsToContents()
  49. # set all row heights
  50. nrows = len(self.mydata)
  51. for row in range(nrows):
  52. tview.setRowHeight(row, 18)
  53. # enable sorting
  54. tview.setSortingEnabled(True)
  55. return tview
  56.  
  57. class MyTableModel(QAbstractTableModel):
  58. def __init__(self, parent, mydata, header, *args):
  59. """
  60. mydata is list of tuples
  61. header is list of strings
  62. tuple length has to match header length
  63. """
  64. QAbstractTableModel.__init__(self, parent, *args)
  65. self.mydata = mydata
  66. self.header = header
  67.  
  68. def rowCount(self, parent):
  69. return len(self.mydata)
  70.  
  71. def columnCount(self, parent):
  72. return len(self.mydata[0])
  73.  
  74. def data(self, index, role):
  75. if not index.isValid():
  76. return QVariant()
  77. elif role != Qt.DisplayRole:
  78. return QVariant()
  79. return QVariant(self.mydata[index.row()][index.column()])
  80.  
  81. def headerData(self, col, orientation, role):
  82. if orientation == Qt.Horizontal and role == Qt.DisplayRole:
  83. return QVariant(self.header[col])
  84. return QVariant()
  85.  
  86. def sort(self, col, order):
  87. """sort table by given column number col"""
  88. self.emit(SIGNAL("layoutAboutToBeChanged()"))
  89. self.mydata = sorted(self.mydata,
  90. key=operator.itemgetter(col))
  91. if order == Qt.DescendingOrder:
  92. self.mydata.reverse()
  93. self.emit(SIGNAL("layoutChanged()"))
  94.  
  95.  
  96. # the test data is from one of vegaseat's codes
  97. # so if there is a mistake don't blame Henri ...
  98. header = [' Symbol ', ' Name ', ' Atomic Weight ',
  99. ' Melt (K) ', ' Boil (K) ']
  100. # use numbers for numeric data to sort properly
  101. element_list = [
  102. ('H', 'Hydrogen', 1.00794, 13.81, 20.28),
  103. ('He', 'Helium', 4.0026, 0.95, 4.216),
  104. ('Li', 'Lithium', 6.941, 453.7, 1615),
  105. ('Be', 'Beryllium', 9.0122, 1560, 3243),
  106. ('B', 'Boron', 10.811, 2365, 4275),
  107. ('C', 'Carbon', 12.011, 3825, 5100),
  108. ('N', 'Nitrogen', 14.0067, 63.15, 77.344),
  109. ('O', 'Oxygen', 15.9994, 54.8, 90.188),
  110. ('F', 'Fluorine', 18.9984, 53.65, 85.0),
  111. ('Ne', 'Neon', 20.1797, 24.55, 27.1),
  112. ('Na', 'Sodium', 22.98977, 371.0, 1156),
  113. ('Mg', 'Magnesium', 24.305, 922, 1380),
  114. ('Al', 'Aluminum', 26.9815, 933.5, 2740),
  115. ('Si', 'Silicon', 28.0855, 1683, 2630),
  116. ('P', 'Phosphorus', 30.9737, 317.3, 553),
  117. ('S', 'Sulfur', 32.066, 392.2, 717.62),
  118. ('Cl', 'Chlorine', 35.4527, 172.17, 239.18),
  119. ('Ar', 'Argon', 39.948, 83.95, 87.45),
  120. ('K', 'Potassium', 39.0983, 336.8, 1033),
  121. ('Ca', 'Calcium', 40.078, 1112, 1757),
  122. ('Sc', 'Scandium', 44.9559, 1814, 3109),
  123. ('Ti', 'Titanium', 47.88, 1935, 3560),
  124. ('V', 'Vanadium', 50.9415, 2136, 3650),
  125. ('Cr', 'Chromium', 51.996, 2130, 2945),
  126. ('Mn', 'Manganese', 54.938, 1518, 2235),
  127. ('Fe', 'Iron', 55.847, 1808, 3023),
  128. ('Co', 'Cobalt', 58.9332, 1768, 3143),
  129. ('Ni', 'Nickel', 58.6934, 1726, 3005),
  130. ('Cu', 'Copper', 63.546, 1356.6, 2840),
  131. ('Zn', 'Zinc', 65.39, 682.73, 1180),
  132. ('Ga', 'Gallium', 69.723, 302.92, 2478),
  133. ('Ge', 'Germanium', 72.61, 1211.5, 3107),
  134. ('As', 'Arsenic', 74.9216, 876.4, 876.3),
  135. ('Se', 'Selenium', 78.96, 494, 958),
  136. ('Br', 'Bromine', 79.904, 265.95, 331.85),
  137. ('Kr', 'Krypton', 83.8, 116, 120.85),
  138. ('Rb', 'Rubidium', 85.4678, 312.63, 961),
  139. ('Sr', 'Strontium', 87.62, 1042, 1655),
  140. ('Y', 'Yttrium', 88.9059, 1795, 3611),
  141. ('Zr', 'Zirconium', 91.224, 2128, 4683),
  142. ('Nb', 'Niobium', 92.9064, 2743, 5015),
  143. ('Mo', 'Molybdenum', 95.94, 2896, 4912),
  144. ('Tc', 'Technetium', 98, 2477, 4538),
  145. ('Ru', 'Ruthenium', 101.07, 2610, 4425),
  146. ('Rh', 'Rhodium', 102.9055, 2236, 3970),
  147. ('Pd', 'Palladium', 106.42, 1825, 3240),
  148. ('Ag', 'Silver', 107.868, 1235.08, 2436),
  149. ('Cd', 'Cadmium', 112.41, 594.26, 1040),
  150. ('In', 'Indium', 114.82, 429.78, 2350),
  151. ('Sn', 'Tin', 118.71, 505.12, 2876),
  152. ('Sb', 'Antimony', 121.757, 903.91, 1860),
  153. ('Te', 'Tellurium', 127.6, 722.72, 1261),
  154. ('I', 'Iodine', 126.9045, 386.7, 457.5),
  155. ('Xe', 'Xenon', 131.29, 161.39, 165.1),
  156. ('Cs', 'Cesium', 132.9054, 301.54, 944),
  157. ('Ba', 'Barium', 137.33, 1002, 2079),
  158. ('La', 'Lanthanum', 138.9055, 1191, 3737),
  159. ('Ce', 'Cerium', 140.12, 1071, 3715),
  160. ('Pr', 'Praseodymium', 140.9077, 1204, 3785),
  161. ('Nd', 'Neodymium', 144.24, 1294, 3347),
  162. ('Pm', 'Promethium', 145, 1315, 3273),
  163. ('Sm', 'Samarium', 150.36, 1347, 2067),
  164. ('Eu', 'Europium', 151.965, 1095, 1800),
  165. ('Gd', 'Gadolinium', 157.25, 1585, 3545),
  166. ('Tb', 'Terbium', 158.9253, 1629, 3500),
  167. ('Dy', 'Dysprosium', 162.5, 1685, 2840),
  168. ('Ho', 'Holmium', 164.9303, 1747, 2968),
  169. ('Er', 'Erbium', 167.26, 1802, 3140),
  170. ('Tm', 'Thulium', 168.9342, 1818, 2223),
  171. ('Yb', 'Ytterbium', 173.04, 1092, 1469),
  172. ('Lu', 'Lutetium', 174.967, 1936, 3668),
  173. ('Hf', 'Hafnium', 178.49, 2504, 4875),
  174. ('Ta', 'Tantalum', 180.9479, 3293, 5730),
  175. ('W', 'Tungsten', 183.85, 3695, 5825),
  176. ('Re', 'Rhenium', 186.207, 3455, 5870),
  177. ('Os', 'Osmium', 190.2, 3300, 5300),
  178. ('Ir', 'Iridium', 192.22, 2720, 4700),
  179. ('Pt', 'Platinum', 195.08, 2042.1, 4100),
  180. ('Au', 'Gold', 196.9665, 1337.58, 3130),
  181. ('Hg', 'Mercury', 200.59, 234.31, 629.88),
  182. ('Tl', 'Thallium', 204.383, 577, 1746),
  183. ('Pb', 'Lead', 207.2, 600.65, 2023),
  184. ('Bi', 'Bismuth', 208.9804, 544.59, 1837),
  185. ('Po', 'Polonium', 209, 527, 1235.15),
  186. ('At', 'Astatine', 210, 575, 610),
  187. ('Rn', 'Radon', 222, 202, 211.4),
  188. ('Fr', 'Francium', 223, 300, 950),
  189. ('Ra', 'Radium', 226.0254, 973, 1413),
  190. ('Ac', 'Actinium', 227, 1324, 3470),
  191. ('Th', 'Thorium', 232.0381, 2028, 5060),
  192. ('Pa', 'Proctactinium', 231.0359, 1845, 4300),
  193. ('U', 'Uranium', 238.029, 1408, 4407),
  194. ('Np', 'Neptunium', 237.0482, 912, 4175),
  195. ('Pu', 'Plutonium', 244, 913, 3505),
  196. ('Am', 'Americium', 243, 1449, 2880),
  197. ]
  198.  
  199. app = QApplication(sys.argv)
  200. win = MyWindow(element_list, header)
  201. win.show()
  202. sys.exit(app.exec_())
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #33
Jul 28th, 2009
Exploring PyQT's QListView and QAbstractListModel. This little code pops up posssible words from word list as you type:
  1. # using PyQT's QListView and QAbstractListModel
  2. # to match partially typed word to words in list
  3. # make matching case insensitive
  4. # tested with Python 3.1 and PyQT 4.5
  5. # Henri
  6.  
  7. import sys
  8. from PyQt4.QtCore import *
  9. from PyQt4.QtGui import *
  10.  
  11. class MyWindow(QWidget):
  12. def __init__(self, words, *args):
  13. QWidget.__init__(self, *args)
  14. # setGeometry(x_pos, y_pos, width, height)
  15. self.setGeometry(300, 300, 320, 250)
  16. self.setWindowTitle("Match words with PyQT's QListView")
  17. self.words = words
  18.  
  19. # create objects
  20. self.label = QLabel("Start typing to match words in list:")
  21. #self.edit = MyLineEdit()
  22. self.edit = QLineEdit()
  23. self.lmodel = MyListModel(self, self.words)
  24. self.lview = QListView()
  25. self.lview.setModel(self.lmodel)
  26.  
  27. # layout
  28. layout = QVBoxLayout()
  29. layout.addWidget(self.label)
  30. layout.addWidget(self.edit)
  31. layout.addWidget(self.lview)
  32. self.setLayout(layout)
  33.  
  34. # one key has been pressed in edit
  35. self.connect(self.edit, SIGNAL("textChanged(QString)"),
  36. self.update)
  37.  
  38. def update(self):
  39. """
  40. updates the list of possible completions each time key
  41. is pressed, use lower() to make things case insensitive
  42. """
  43. p = str(self.edit.text()).lower()
  44. new_list = [w for w in self.words if w.lower().find(p)==0]
  45. self.lmodel.setAllData(new_list)
  46.  
  47.  
  48. class MyListModel(QAbstractListModel):
  49. def __init__(self, parent, words, *args):
  50. """
  51. words is list of words
  52. """
  53. QAbstractListModel.__init__(self, parent, *args)
  54. self.words = words
  55.  
  56. def rowCount(self, parent=QModelIndex()):
  57. return len(self.words)
  58.  
  59. def data(self, index, role):
  60. if index.isValid() and role == Qt.DisplayRole:
  61. return QVariant(self.words[index.row()])
  62. else:
  63. return QVariant()
  64.  
  65. def setAllData(self, new_list):
  66. """replace old list with new list"""
  67. self.words = new_list
  68. self.reset()
  69.  
  70.  
  71. # this is just test list of words
  72. state_list = [
  73. 'Mississippi', 'Oklahoma', 'Delaware', 'Minnesota',
  74. 'Arkansas', 'New Mexico', 'Indiana', 'Louisiana',
  75. 'Texas', 'Wisconsin', 'Kansas', 'Connecticut',
  76. 'California', 'West Virginia', 'Georgia', 'North Dakota',
  77. 'Pennsylvania', 'Alaska', 'Missouri', 'South Dakota',
  78. 'Colorado', 'New Jersey', 'Washington', 'New York',
  79. 'Nevada', 'Maryland', 'Idaho', 'Wyoming', 'Maine',
  80. 'Arizona', 'Iowa', 'Michigan', 'Utah', 'Illinois',
  81. 'Virginia', 'Oregon', 'Montana', 'New Hampshire',
  82. 'Massachusetts', 'South Carolina', 'Vermont', 'Florida',
  83. 'Hawaii', 'Kentucky', 'Rhode Island', 'Nebraska',
  84. 'Ohio', 'Alabama', 'North Carolina', 'Tennessee'
  85. ]
  86.  
  87. app = QApplication(sys.argv)
  88. win = MyWindow(state_list)
  89. win.show()
  90. sys.exit(app.exec_())
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #34
Jul 29th, 2009
One more simple way to present data in table form:
  1. # use PyQT's QTableWidget, QTableWidgetItem and setItem
  2. # to show data in simple table format
  3. # tested with Python 3.1 and PyQT 4.5
  4. # Henri
  5.  
  6. import sys
  7. # simplified import
  8. from PyQt4.QtCore import *
  9. from PyQt4.QtGui import *
  10.  
  11. class MyTable(QTableWidget):
  12. def __init__(self, data, rows, cols):
  13. QTableWidget.__init__(self, rows, cols)
  14. # setGeometry(x_pos, y_pos, width, height)
  15. self.setGeometry(300, 200, 280, 180)
  16. self.setWindowTitle("Simple QTableWidget")
  17. self.data = data
  18. self.set_data()
  19.  
  20. def set_data(self):
  21. """self.data is list of (fname, sname, age) tuples"""
  22. row = 0
  23. for tup in self.data:
  24. col = 0
  25. for item in tup:
  26. newitem = QTableWidgetItem(item)
  27. self.setItem(row, col, newitem)
  28. col += 1
  29. row += 1
  30.  
  31.  
  32. # fname, sname, age raw data for instance from file
  33. staff = """\
  34. Frank, Marco, 27
  35. Henri, Poulong, 34
  36. Gisela, Lang, 19
  37. Lance, Handy, 46"""
  38.  
  39. # create list of (fname, sname, age) tuples
  40. data = []
  41. for line in staff.split('\n'):
  42. fname, sname, age = line.split(',')
  43. data.append((fname.strip(), sname.strip(), age.strip()))
  44.  
  45. app = QApplication(sys.argv)
  46. rows = 5
  47. cols = 3
  48. table = MyTable(data, rows, cols)
  49. table.show()
  50. sys.exit(app.exec_())
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,273
Reputation: sneekula has a spectacular aura about sneekula has a spectacular aura about 
Solved Threads: 175
sneekula's Avatar
sneekula sneekula is offline Offline
Nearly a Posting Maven

Re: Python GUI Programming

 
1
  #35
Aug 1st, 2009
Some options with a basic Tkinter window:
  1. # set position and size of a Tkinter window
  2.  
  3. try:
  4. # for Python2
  5. import Tkinter as tk
  6. except ImportError:
  7. # for Python3
  8. import tkinter as tk
  9.  
  10. #root = tk.Tk()
  11. root = tk.Tk(className="My Title") # sets title too
  12. # or give it your title this way
  13. #root.title("My Title")
  14.  
  15. w = 300
  16. h = 200
  17. x = 50
  18. y = 100
  19. # use width x height + x_offset + y_offset (no spaces!)
  20. root.geometry("%dx%d+%d+%d" % (w, h, x, y))
  21.  
  22. # make Tk window not resizable, also disables the maximize button
  23. #root.resizable(width=FALSE, height=FALSE)
  24. # or ...
  25. #root.resizable(0, 0)
  26.  
  27. # or make root window full screen
  28. #root.state('zoomed')
  29.  
  30. # give it a colorful frame
  31. frame = tk.Frame(root, bg='green')
  32. frame.pack(fill='both', expand='yes')
  33.  
  34. root.mainloop()
No one died when Clinton lied.
Reply With Quote Quick reply to this message  
Join Date: Oct 2006
Posts: 2,273
Reputation: sneekula has a spectacular aura about sneekula has a spectacular aura about 
Solved Threads: 175
sneekula's Avatar
sneekula sneekula is offline Offline
Nearly a Posting Maven

Re: Python GUI Programming

 
1
  #36
Aug 1st, 2009
For those of you who want experience vegaseat's sweet Tinter tkk example at:
http://www.daniweb.com/forums/post921416-25.html
on your Linux machines, in my case Ubuntu (Python 3.1 is not in the repository yet), here is an easy installation of Python 3.1:

Download ActivePython-3.1.0.1-linux-x86.tar.gz via
http://downloads.activestate.com/Act...nux-x86.tar.gz
from:
http://www.activestate.com/activepython/python3/

Extract to the Desktop

In the terminal change to the proper directory:

cd ~/Desktop/ActivePython-3.1.0.1-linux-x86/

Then run:

sudo ./install.sh

As install directory I entered something easy like:

/home/dell/python/3.1

The installation takes a short time. Now create a symbolic link:

sudo ln -s /home/dell/python/3.1/bin/python3.1 /usr/local/bin/python3.1

Now you are ready to enjoy Python 3.1

# to run a scripts with Python3.1
# with the Geany IDE you can set 'Build'/'Set Includes and Arguments'
# 'Execute' to python3.1 "%f"
Last edited by sneekula; Aug 1st, 2009 at 7:09 pm.
No one died when Clinton lied.
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #37
Aug 3rd, 2009
One nice graphical way to select calendar date is with the calendar widget. Here is the PyQT example:
  1. # explore the PyQT QCalendarWidget widget
  2. # tested with Python 3.1 and PyQT 4.5
  3. # Henri
  4.  
  5. import sys
  6. from PyQt4.QtCore import *
  7. from PyQt4.QtGui import *
  8.  
  9. class MyCalendar(QWidget):
  10. def __init__(self, parent=None):
  11. QWidget.__init__(self, parent)
  12. # setGeometry(x_pos, y_pos, width, height)
  13. self.setGeometry(300, 300, 280, 220)
  14. self.setWindowTitle('Calendar')
  15.  
  16. self.calendar = QCalendarWidget(self)
  17. self.calendar.setGridVisible(True)
  18. # use absolute layout (x_pos, y_pos) for widgets
  19. self.calendar.move(20, 20)
  20. self.connect(self.calendar, SIGNAL('selectionChanged()'),
  21. self.show_date)
  22.  
  23. self.label = QLabel(self)
  24. self.label.move(120, 180)
  25.  
  26. self.label2 = QLabel(self)
  27. self.label2.setGeometry(85, 200, 150, 20)
  28.  
  29. # show initial date
  30. self.show_date()
  31.  
  32. def show_date(self):
  33. date = self.calendar.selectedDate()
  34. # to get month/day/year like '8/13/2009' use ...
  35. s = "%s/%s/%s" % (date.month(), date.day(), date.year())
  36. self.setWindowTitle(s) # test
  37. # date.toPyDate() gives year-month-day like '2009-8-13'
  38. self.label.setText(str(date.toPyDate()))
  39. # or you can use Qdate formatted string
  40. # to show something like 'Thursday August 13 2009'
  41. s2 = date.toString('dddd MMMM d yyyy')
  42. self.label2.setText(s2)
  43.  
  44.  
  45. app = QApplication(sys.argv)
  46. mc = MyCalendar()
  47. mc.show()
  48. app.exec_()
Last edited by bumsfeld; Aug 3rd, 2009 at 8:50 pm.
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #38
Aug 4th, 2009
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:
  1. # pqt_listbox2.py
  2. # explore PyQT's QListWidget (list box) actions
  3. # tested with Python 3.1 and PyQT 4.5
  4. # Henri
  5.  
  6. import sys
  7. from PyQt4.QtCore import *
  8. from PyQt4.QtGui import *
  9.  
  10. class MyFrame(QWidget):
  11. def __init__(self, coffee_list, parent=None):
  12. QWidget.__init__(self, parent)
  13. # setGeometry(x_pos, y_pos, width, height)
  14. self.setGeometry(100, 150, 420, 150)
  15. self.setWindowTitle('Things to do with QListWidget')
  16.  
  17. self.coffee_list = coffee_list
  18.  
  19. self.listbox = QListWidget()
  20. self.connect(self.listbox, SIGNAL("itemSelectionChanged()"),
  21. self.on_select)
  22.  
  23. # use grid layout to position the widgets
  24. grid = QGridLayout(self)
  25. # addWidget(QWidget, row, column, rowSpan, columnSpan)
  26. grid.addWidget(self.listbox, 0, 0, 7, 2)
  27.  
  28. # list of (btn_text, action_method) tuples
  29. btn_action = [
  30. ("Load", self.lb_load),
  31. ("Sort", self.listbox.sortItems),
  32. ("Move Down", self.lb_down),
  33. ("Move Up", self.lb_up),
  34. ("Remove Line", self.lb_remove),
  35. ("Add Line", self.lb_add),
  36. ("Edit Line", self.lb_edit)]
  37. # the standard button is the QPushButton widget
  38. # create multiple buttons using the for loop
  39. row = 0
  40. for text, action in btn_action:
  41. button = QPushButton(text)
  42. grid.addWidget(button, row, 2, 1, 1)
  43. self.connect(button, SIGNAL("clicked()"), action)
  44. row += 1
  45. self.setLayout(grid)
  46.  
  47.  
  48. def lb_load(self):
  49. """list box load"""
  50. # clear any existing data first
  51. self.listbox.clear()
  52. self.listbox.addItems(self.coffee_list)
  53. # start with first line selected (highlighted)
  54. self.listbox.setCurrentRow(0)
  55.  
  56. def lb_down(self):
  57. """move selected item down one list box line"""
  58. row = self.listbox.currentRow()
  59. if row < self.listbox.count() - 1:
  60. item = self.listbox.takeItem(row)
  61. self.listbox.insertItem(row + 1, item)
  62. self.listbox.setCurrentItem(item)
  63.  
  64. def lb_up(self):
  65. """move selected item up one list box line"""
  66. row = self.listbox.currentRow()
  67. if row >= 1:
  68. item = self.listbox.takeItem(row)
  69. self.listbox.insertItem(row - 1, item)
  70. self.listbox.setCurrentItem(item)
  71.  
  72. def lb_remove(self):
  73. """remove selected item from the list box"""
  74. row = self.listbox.currentRow()
  75. item = self.listbox.takeItem(row)
  76. del item
  77.  
  78. def lb_add(self):
  79. """add new line to list box above current line"""
  80. row = self.listbox.currentRow()
  81. title = "Add new coffee"
  82. text, ok = QInputDialog.getText(self, title, title)
  83. if ok and not text.isEmpty():
  84. self.listbox.insertItem(row, text)
  85.  
  86. def lb_edit(self):
  87. """edit selected item via popup dialog window"""
  88. row = self.listbox.currentRow()
  89. item = self.listbox.item(row)
  90. if item is not None:
  91. title = "Edit the Coffee"
  92. text, ok = QInputDialog.getText(self, title, title,
  93. QLineEdit.Normal, item.text())
  94. if ok and not text.isEmpty():
  95. item.setText(text)
  96.  
  97. def on_select(self):
  98. """an item in the listbox has been clicked/selected"""
  99. try:
  100. selected_name = self.listbox.selectedItems()[0].text()
  101. s = "selected = %s" % selected_name
  102. self.setWindowTitle(s)
  103. except:
  104. pass
  105.  
  106.  
  107. coffee_list = ['Irish Coffee (Whisky)', 'Brandy Coffee (Brandy)',
  108. 'English Coffee (Gin)', 'Calypso Coffee (Kahlua and Rum)',
  109. 'Jamaican Coffee (Tia Maria and Rum)', 'Shin Shin Coffee (Rum)',
  110. 'Baileys Irish Cream Coffee', "Monk's Coffee (Benedictine)",
  111. 'Seville Coffee (Cointreau)', "Witch's Coffee (Strega)",
  112. 'Russian Coffee (Vodka)', 'Australian Coffee (Cask Wine/Goon)',
  113. 'Corfu Coffee (Koum Quat liquor)', 'Kaffee Fertig (Prune Schnaps)',
  114. 'Caffe corretto (grappa)']
  115.  
  116. app = QApplication(sys.argv)
  117. frame = MyFrame(coffee_list)
  118. frame.show()
  119. sys.exit(app.exec_())
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #39
Aug 5th, 2009
Sometimes it's nice to attach label to entry widget. One way to do this is with class object:
  1. # pqt_EntryLab1.py
  2. # create labeled data entry areas
  3. # tested with Python 3.1 and PyQT 4.5
  4. # Henri
  5.  
  6. import sys
  7. from PyQt4.QtCore import *
  8. from PyQt4.QtGui import *
  9.  
  10. class MyFrame(QWidget):
  11. def __init__(self, parent=None):
  12. QWidget.__init__(self, parent)
  13. # setGeometry(x_pos, y_pos, width, height)
  14. self.setGeometry(100, 150, 300, 150)
  15. self.setWindowTitle('data entry with attached label')
  16.  
  17. # label to the 'left' side is default
  18. self.e_name = LEditLab(self, "Enter your name:")
  19. self.e_age = LEditLab(self, "Enter your age: ")
  20. self.e_job = LEditLab(self, "Enter your job: ")
  21. # display result 2 different ways, label on top
  22. self.e_result2 = LEditLab(self, "Result: ", 'top')
  23. self.e_result = EditLab(self, "Result:", 'top')
  24.  
  25. self.b_done = QPushButton("Done")
  26.  
  27. # use a grid layout to position the widgets
  28. # note that the grid is centered on the frame
  29. grid = QGridLayout(self)
  30. # addWidget(QWidget, row, column, rowSpan, columnSpan)
  31. grid.addWidget(self.e_name, 0, 0, 1, 3)
  32. grid.addWidget(self.e_age, 1, 0, 1, 3)
  33. grid.addWidget(self.e_job, 2, 0, 1, 3)
  34. grid.addWidget(self.b_done, 3, 1, 1, 1)
  35. grid.addWidget(self.e_result2, 4, 0, 1, 3)
  36. grid.addWidget(self.e_result, 5, 0, 1, 3)
  37. self.setLayout(grid)
  38.  
  39. # connect the button click signal to an action
  40. self.connect(self.b_done, SIGNAL("clicked()"), self.action)
  41.  
  42. def action(self):
  43. name = self.e_name.text()
  44. age = self.e_age.text()
  45. job = self.e_job.text()
  46. s2 = "%s, %s, %s" % (name, age, job)
  47. self.e_result2.setText(s2)
  48. s = "%s\n%s\n%s\n" % (name, age, job)
  49. self.e_result.setText(s)
  50.  
  51.  
  52. class LEditLab(QWidget):
  53. """label QLineEdit data entry/display to the left or on top"""
  54. def __init__(self, parent, mytext=QString(), pos='left'):
  55. QWidget.__init__(self, parent)
  56. self.label = QLabel(mytext)
  57. self.edit = QLineEdit()
  58. label_pos = QBoxLayout.LeftToRight if pos == 'left' \
  59. else QBoxLayout.TopToBottom
  60. layout = QBoxLayout(label_pos)
  61. layout.addWidget(self.label)
  62. layout.addWidget(self.edit)
  63. self.setLayout(layout)
  64.  
  65. def text(self):
  66. """create QLineEdit() like method to get text"""
  67. return self.edit.text()
  68.  
  69. def setText(self, text):
  70. """create QLineEdit() like method to set text"""
  71. return self.edit.setText(text)
  72.  
  73.  
  74. class EditLab(QWidget):
  75. """label QEdit data entry/display area to the left or on top"""
  76. def __init__(self, parent, mytext=QString(), pos='left'):
  77. QWidget.__init__(self, parent)
  78. self.label = QLabel(mytext)
  79. self.edit = QTextEdit()
  80. label_pos = QBoxLayout.LeftToRight if pos == 'left' \
  81. else QBoxLayout.TopToBottom
  82. layout = QBoxLayout(label_pos)
  83. layout.addWidget(self.label)
  84. layout.addWidget(self.edit)
  85. self.setLayout(layout)
  86.  
  87. def setText(self, text):
  88. """create QTextEdit() like method to set text"""
  89. return self.edit.setText(text)
  90.  
  91. def getText(self):
  92. """
  93. create method to get text
  94. use better syntax than QTextEdit()
  95. """
  96. return self.edit.toPlainText()
  97.  
  98.  
  99. app = QApplication(sys.argv)
  100. frame = MyFrame()
  101. frame.show()
  102. sys.exit(app.exec_())
Should work with Python2 versions too.
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Join Date: Jul 2005
Posts: 1,221
Reputation: bumsfeld will become famous soon enough bumsfeld will become famous soon enough 
Solved Threads: 137
bumsfeld's Avatar
bumsfeld bumsfeld is offline Offline
Nearly a Posting Virtuoso

Re: Python GUI Programming

 
1
  #40
Aug 5th, 2009
Exampled code for PyQT's multiline text entry widget:
  1. # pqt_TextEdit1.py
  2. # explore PyQT's QTextEdit multiline text entry box
  3. # click right mouse button in edit area for popup menu
  4. # Henri
  5.  
  6. import sys
  7. from PyQt4.QtCore import *
  8. from PyQt4.QtGui import *
  9.  
  10. class MyFrame(QWidget):
  11. def __init__(self, parent=None):
  12. QWidget.__init__(self, parent)
  13. # setGeometry(x_pos, y_pos, width, height)
  14. self.setGeometry(100, 50, 300, 180)
  15. self.setWindowTitle('QTextEdit() test')
  16.  
  17. self.edit = QTextEdit(self)
  18. self.edit.append('just some text,\n you can append more')
  19. self.edit.append('well, here is more!!!')
  20. self.edit.append('click the right mouse button')
  21. self.edit.append('to get option popup menu\n')
  22.  
  23. self.pbutton = QPushButton(self)
  24. self.pbutton.setText(' transfer text to label ')
  25.  
  26. # label auto-adjusts to multiple lines
  27. self.label = QLabel(self)
  28. self.label.setText('label ...')
  29.  
  30. # use grid layout manager
  31. grid = QGridLayout(self)
  32. # addWidget(QWidget, row, column, rowSpan, columnSpan)
  33. grid.addWidget(self.pbutton, 0, 0, 1, 1)
  34. grid.addWidget(self.edit, 1, 0, 1, 2)
  35. grid.addWidget(self.label, 2, 0, 1, 2)
  36. self.setLayout(grid)
  37.  
  38. # bind the button clicked to action
  39. self.connect(self.pbutton, SIGNAL("clicked()"), self.action)
  40.  
  41. def action(self):
  42. # get the text from self.edit
  43. text = self.edit.toPlainText()
  44. # put the text into self.label
  45. self.label.setText(text)
  46.  
  47.  
  48. app = QApplication(sys.argv)
  49. frame = MyFrame()
  50. frame.show()
  51. sys.exit(app.exec_())
Should you find Irony, you can keep her!
Reply With Quote Quick reply to this message  
Reply

Message:


Thread Tools Search this Thread



About Us | Contact Us | Advertise | DaniWeb | Acceptable Use Policy | RSS Feed

©2003 - 2009 DaniWeb® LLC