| *setSpacing*: le due precedenti, combinate. | | *setSpacing*: le due precedenti, combinate. |
| *setColumnMinimumWidth*: larghezza minima della co | | *setColumnMinimumWidth*: larghezza minima della co |
| lonna specificata come primo parametro. | | lonna specificata come primo parametro. |
| *setRowMinimumWidth*: stessa cosa per una riga. | | *setRowMinimumWidth*: stessa cosa per una riga. |
| *int columnCount*: ritorna il numero di colonne de | | *int columnCount*: ritorna il numero di colonne de |
| lla griglia. | | lla griglia. |
| *int rowCount*: ritorna il numero di righe. | | *int rowCount*: ritorna il numero di righe. |
t | | t |
|
| | | Menu
|
| | | #####
|
| | |
|
| | | Andiamo a definire un semplice menu.::
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | |
|
| | | def mySlot(self):
|
| | | print "Menu voice has been hovered |
| | | "
|
| | |
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | | self.setWindowTitle('Menu')
|
| | |
|
| | | quit = QtGui.QAction(QtGui.QIcon(" |
| | | icons/cancel.png"), "Quit", self)
|
| | | quit.setShortcut("Ctrl+Q")
|
| | | quit.setStatusTip("Quit applicatio |
| | | n")
|
| | | self.connect(quit, QtCore.SIGNAL(' |
| | | triggered()'), QtCore.SLOT('close()'))
|
| | |
|
| | | sep = QtGui.QAction(self)
|
| | | sep.setSeparator(True)
|
| | |
|
| | | info = QtGui.QAction(QtGui.QIcon(" |
| | | icons/information.png"), "Information", self)
|
| | | info.setShortcut("Ctrl+I")
|
| | | info.setStatusTip("Show informatio |
| | | n")
|
| | | self.connect(info, QtCore.SIGNAL(' |
| | | hovered()'), self.mySlot)
|
| | |
|
| | | self.statusBar().show()
|
| | |
|
| | | menuB = self.menuBar()
|
| | | file = menuB.addMenu('&File')
|
| | | file.addAction(quit)
|
| | | file.addAction(sep)
|
| | | file.addAction(info)
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | .. img:: 12
|
| | | :nolink:
|
| | |
|
| | | In ordine di “importanza”, i passi sono:
|
| | |
|
| | | * creare una menuBar (la nostra menuB)
|
| | | * aggiungere tutti i menu che vogliamo creare con |
| | | il metodo *addMenu()*. Questo metodo prende come a |
| | | rgomento una stringa. Il carattere preceduto dal s |
| | | imbolo & funge da scorciatoia: premendo Alt+caratt |
| | | ere attiveremo il menu corrispondente.
|
| | | * Ad ogni menu vanno poi aggiunge le singole *QAct |
| | | ion*, ovvero le voci di menu.::
|
| | |
|
| | | quit = QtGui.QAction(QtGui.QIcon(" |
| | | icons/cancel.png"), "Quit", self)
|
| | | quit.setShortcut("Ctrl+Q")
|
| | | quit.setStatusTip("Quit applicatio |
| | | n")
|
| | | self.connect(quit, QtCore.SIGNAL(' |
| | | triggered()'), QtCore.SLOT('close()'))
|
| | |
|
| | | Il costruttore di *QAction* permette di specificar |
| | | e subito il path dell'icona e il testo della voce |
| | | di menu, oppure di ometterlo e di indicarlo dopo c |
| | | on i metodi appositi:::
|
| | |
|
| | | quit = QtGui.QAction(self)
|
| | | quit.setText(“Quit”)
|
| | | quit.setIcon(QtGui.QIcon(“icons/qu |
| | | it.png”)
|
| | |
|
| | | Questi ultimi due codici danno lo stesso identico |
| | | risultato.
|
| | | Il metodo *setText()* merita particolare attenzion |
| | | e: infatti esso si può trovare in diversi widget c |
| | | he comprendono un testo (pulsanti, etichette, etc. |
| | | ..) per modificare il testo che accompagna il widg |
| | | et stesso. Il corrispondente che invece ritorna il |
| | | testo corrente sotto forma di *QString* è semplic |
| | | emente *text()*.
|
| | | Eccezione: per le *textEdit*, che possono contener |
| | | e non solo testo semplice ma anche HTML, invece di |
| | | *text()* si ha *toPlainText()*.
|
| | | Per ritornare la shortcut o lo statustip correnti |
| | | potete usare i metodi *statusTip()* e *shortcut()* |
| | | .
|
| | | Il secondo oggetto non rappresenta una voce di men |
| | | u, ma semplicemente un separatore: per questo nel |
| | | costruttore non passiamo nessun argomento.
|
| | |
|
| | | Nel codice precedente sono mostrati due segnali ti |
| | | pici dei menu: *triggered()* viene emesso quando l |
| | | 'utente clicca su una voce di menu. ATTENZIONE: no |
| | | n viene dunque emesso il segnale *clicked()* come |
| | | si potrebbe pensare! Invece *hovered()* è emesso q |
| | | uando il mouse passa sulla voce di menu.
|
| | | Ultima nota: per le voci di menu è presente anche |
| | | il metodo *setCheckable()* (e *setChecked()*, per |
| | | specificare l'azione iniziale), identico a quello |
| | | usato per i toggle button in precedenza: se viene |
| | | passato il parametro True, l'icona della voce si c |
| | | omporterà proprio come un toggle button.
|
| | |
|
| | | Toolbar
|
| | | ########
|
| | |
|
| | | Una toolbar è un insieme di pulsanti che assolvono |
| | | ad alcune funzioni di base. In alcuni casi può es |
| | | sere più comoda di un menu perché permette all'ute |
| | | nte di scegliere l'azione più velocemente.::
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | |
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | |
|
| | | self.setWindowTitle('Toolbar')
|
| | |
|
| | | quit = QtGui.QAction(QtGui.QIcon(" |
| | | icons/cancel.png"), "Quit", self)
|
| | | quit.setShortcut("Ctrl+Q")
|
| | | quit.setStatusTip("Quit applicatio |
| | | n")
|
| | | self.connect(quit, QtCore.SIGNAL(' |
| | | triggered()'), QtCore.SLOT('close()'))
|
| | |
|
| | | sep = QtGui.QAction(self)
|
| | | sep.setSeparator(True)
|
| | |
|
| | | info = QtGui.QAction(QtGui.QIcon(" |
| | | icons/information.png"), "Info", self)
|
| | | info.setShortcut("Ctrl+I")
|
| | | info.setStatusTip("Show informatio |
| | | n")
|
| | |
|
| | | self.statusBar().show()
|
| | |
|
| | | toolbar = self.addToolBar('My tool |
| | | ')
|
| | | toolbar.addAction(quit)
|
| | | toolbar.addAction(info)
|
| | | toolbar.setToolButtonStyle(QtCore. |
| | | Qt.ToolButtonTextUnderIcon)
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | .. img:: 15
|
| | | :nolink:
|
| | |
|
| | | Come è possibile notare, il codice non è troppo di |
| | | verso da quello usato per i menu. Le varie “action |
| | | ” si dichiarano sempre allo stesso modo, ma alla f |
| | | ine invece di dichiarare barre e menu, ci limitiam |
| | | o ad una toolbar.
|
| | | Il metodo *setToolButtonStyle()* permette di speci |
| | | ficare la presenza del testo e nel caso, la sua po |
| | | sizione. Gli argomenti che possiamo passargli (olt |
| | | re a quello indicato, che posiziona il testo sotto |
| | | l'icona) sono: *Qt.ToolButtonTextBesideIcon* (tes |
| | | to accanto all'icona), *Qt.ToolButtonTextOnly* (so |
| | | lo testo), *Qt.ToolButtonIconOnly* (solo l'icona, |
| | | l'azione predefinita).
|
| | | Altro metodo è *setOrientation()*: accetta come ar |
| | | gomenti *Qt.Horizontal* o *Qt.Vertical*.
|
| | |
|
| | | Dialogs
|
| | | ########
|
| | |
|
| | | Le dialog window sono “popup”, piccole finestrelle |
| | | che possono essere dipendenti o meno da quella pr |
| | | incipale. Vengono utilizzate per visualizzare brev |
| | | i messaggi o per prendere input.
|
| | | PyQt4 mette a disposizione diversi dialogs standar |
| | | d per le operazioni più comuni: vediamo in un unic |
| | | o codice come si dichiarano, e come vengono ritorn |
| | | ate le informazioni.::
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | | buttons = [0] * 13
|
| | | self.titles = ["Get integer", "Get |
| | | double", "Get item", "Get text", "Set color", "Se |
| | | t font", "Set directory", "Open file", "Save File" |
| | | , "Critical message", "Info message", "Question", |
| | | "Warning"]
|
| | | slots = [self.getInt, self.getDoub |
| | | le, self.getItem, self.getText, self.getColor, sel |
| | | f.getFont, self.getDirectory, self.openFile, self. |
| | | saveFile, self.Critical, self.Info, self.Question, |
| | | self.Warning]
|
| | |
|
| | | self.resize(350, 250)
|
| | | self.setWindowTitle('Dialogs')
|
| | |
|
| | | widget = QtGui.QWidget(self)
|
| | |
|
| | | grid = QtGui.QGridLayout(widget)
|
| | | grid.setVerticalSpacing(10)
|
| | | grid.setHorizontalSpacing(8)
|
| | |
|
| | | row = 0
|
| | | col = 0
|
| | |
|
| | | for i in range(13):
|
| | | buttons[i] = QtGui.QPushBu |
| | | tton(self.titles[i], widget)
|
| | | self.connect(buttons[i], Q |
| | | tCore.SIGNAL('clicked()'), slots[i])
|
| | |
|
| | | grid.addWidget(buttons[i], |
| | | row, col)
|
| | |
|
| | | if col == 2:
|
| | | col = 0
|
| | | row += 1
|
| | | else:
|
| | | col += 1
|
| | |
|
| | | self.textEdit = QtGui.QTextEdit(wi |
| | | dget)
|
| | | self.textEdit.setReadOnly(True)
|
| | | grid.addWidget(self.textEdit, 5, 0 |
| | | , 1, 3)
|
| | |
|
| | | self.setLayout(grid)
|
| | | self.setCentralWidget(widget)
|
| | |
|
| | | def getInt(self):
|
| | | integer, ok = QtGui.QInputDialog.g |
| | | etInteger(self, self.titles[0], "Integer: ", 9, 0, |
| | | 1000, 1)
|
| | |
|
| | | if ok:
|
| | | self.textEdit.append(self. |
| | | tr("%1").arg(integer))
|
| | |
|
| | | def getDouble(self):
|
| | | double, ok = QtGui.QInputDialog.ge |
| | | tDouble(self, self.titles[1], self.tr("Amount:"), |
| | | 37.56, -10000, 10000, 1)
|
| | |
|
| | | if ok:
|
| | | self.textEdit.append(self. |
| | | tr("%1").arg(double))
|
| | |
|
| | | def getItem(self):
|
| | | items = QtCore.QStringList()
|
| | | items << "GNU/Linux" << "Windows" |
| | | << "Macintosh" << "QNX"
|
| | |
|
| | | item, ok = QtGui.QInputDialog.getI |
| | | tem(self, self.titles[2], "OS", items, 0, False)
|
| | |
|
| | | if ok and item.isEmpty() == False: |
| | |
|
| | | self.textEdit.append(item) |
| | |
|
| | |
|
| | | def getText(self):
|
| | | text, ok = QtGui.QInputDialog.getT |
| | | ext(self, self.titles[3], "Enter your name:")
|
| | |
|
| | | if ok and text.isEmpty() == False: |
| | |
|
| | | self.textEdit.append(text) |
| | |
|
| | |
|
| | | def getColor(self):
|
| | | color = QtGui.QColorDialog.getColo |
| | | r(QtCore.Qt.blue, self)
|
| | |
|
| | | if color.isValid():
|
| | | self.textEdit.setTextColor |
| | | (color)
|
| | | self.textEdit.append(color |
| | | .name())
|
| | |
|
| | | def getFont(self):
|
| | | font, ok = QtGui.QFontDialog.getFo |
| | | nt()
|
| | |
|
| | | if ok:
|
| | | self.textEdit.setFont(font |
| | | )
|
| | | self.textEdit.append(font. |
| | | key())
|
| | |
|
| | | def getDirectory(self):
|
| | | directory = QtGui.QFileDialog.getE |
| | | xistingDirectory(self, self.titles[6], "Select dir |
| | | ectory:", QtGui.QFileDialog.ShowDirsOnly)
|
| | |
|
| | | if directory.isEmpty() == False:
|
| | | self.textEdit.append(direc |
| | | tory)
|
| | |
|
| | | def openFile(self):
|
| | | fName = QtGui.QFileDialog.getOpenF |
| | | ileName(self, self.titles[7], "Open new file", sel |
| | | f.tr("All Files (*);;Text Files (*txt)"))
|
| | |
|
| | | if fName.isEmpty() == False:
|
| | | self.textEdit.append(fName |
| | | )
|
| | |
|
| | | def saveFile(self):
|
| | | fName = QtGui.QFileDialog.getSaveF |
| | | ileName(self, self.titles[8], "Save a new file", s |
| | | elf.tr("All Files(*)"))
|
| | |
|
| | | if fName.isEmpty() == False:
|
| | | self.textEdit.append(fName |
| | | )
|
| | |
|
| | | def Critical(self):
|
| | | reply = QtGui.QMessageBox.critical |
| | | (self, self.titles[9], "Critical message!", QtGui. |
| | | QMessageBox.Abort, QtGui.QMessageBox.Ignore, QtGui |
| | | .QMessageBox.Retry)
|
| | |
|
| | | if reply == QtGui.QMessageBox.Abor |
| | | t:
|
| | | self.textEdit.append("Abor |
| | | t")
|
| | | elif reply == QtGui.QMessageBox.Re |
| | | try:
|
| | | self.textEdit.append("Retr |
| | | y")
|
| | | else:
|
| | | self.textEdit.append("Igno |
| | | re")
|
| | |
|
| | | def Info(self):
|
| | | QtGui.QMessageBox.information(self |
| | | , self.titles[10], "Information message")
|
| | |
|
| | | def Question(self):
|
| | | reply = QtGui.QMessageBox.question |
| | | (self, self.titles[11], "Are you sure?", QtGui.QMe |
| | | ssageBox.Yes, QtGui.QMessageBox.No)
|
| | |
|
| | | if reply == QtGui.QMessageBox.Yes: |
| | |
|
| | | self.textEdit.append("Yes" |
| | | )
|
| | | else:
|
| | | self.textEdit.append("No") |
| | |
|
| | |
|
| | | def Warning(self):
|
| | | reply = QtGui.QMessageBox.warning( |
| | | self, self.titles[12], "Warning!", "Try again", "C |
| | | ontinue")
|
| | |
|
| | | if reply == 0:
|
| | | self.textEdit.append("Try |
| | | again")
|
| | | else:
|
| | | self.textEdit.append("Cont |
| | | inue")
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | Per guadagnare in chiarezza, abbiamo posto i pulsa |
| | | nti, i testi degli stessi e gli slots in degli arr |
| | | ay. Il codice all'interno del ciclo for si occupa |
| | | di inizializzarli e sistemarli all'interno della g |
| | | riglia.::
|
| | |
|
| | | integer, ok = QtGui.QInputDialog.g |
| | | etInteger(self, self.titles[0], "Integer: ", 9, 0, |
| | | 1000, 1)
|
| | |
|
| | | Il metodo *getInteger()* richiede i seguenti param |
| | | etri: *self*, una stringa da usare come titolo, un |
| | | 'altra da inserire all'interno del dialog, e quatt |
| | | ro valori numerici. Il primo indica il valore di d |
| | | efault, il secondo il valore minimo selezionabile, |
| | | il terzo il valore massimo, e infine l'ultimo val |
| | | ore indica di quanti numeri si deve andare avanti/ |
| | | indietro quando si premono le freccette a lato. Ad |
| | | esempio se mettete 2, e poi cliccate sulla frecce |
| | | tta in alto, si passerà da 9 direttamente ad 11.:: |
| | |
|
| | |
|
| | | double, ok = QtGui.QInputDialog.ge |
| | | tDouble(self, self.titles[1], self.tr("Amount:"), |
| | | 37.56, -10000, 10000, 1)
|
| | |
|
| | | Cosa simile vale per l'input di valori double, ovv |
| | | ero con virgola mobile.::
|
| | |
|
| | | items << "GNU/Linux" << "Windows" |
| | | << "Macintosh" << "QNX"
|
| | |
|
| | | item, ok = QtGui.QInputDialog.getI |
| | | tem(self, self.titles[2], "OS", items, 0, False)
|
| | |
|
| | | In questo dialog, ci viene proposta una scelta fra |
| | | degli elementi predefiniti. La variabile *items* |
| | | li contiene. Gli ultimi due parametri di *getItem( |
| | | )* indicano rispettivamente l'indice della stringa |
| | | da visualizzare di default e un'indicazione rispe |
| | | tto al layout. Provare a sostituire False con True |
| | | per vedere la differenza.::
|
| | |
|
| | | def getColor(self):
|
| | | color = QtGui.QColorDialog.getColo |
| | | r(QtCore.Qt.blue, self)
|
| | |
|
| | | Qui l'unico parametro interessante è il primo: il |
| | | colore di default. È un parametro opzionale, e se |
| | | viene omesso è settato a *QtCore.Qt.white*.
|
| | |
|
| | | Altri widgets
|
| | | ##############
|
| | |
|
| | | textEdit
|
| | | =========
|
| | |
|
| | | Anche se abbiamo già incontrato questo widget in p |
| | | recedenza, in realtà esistono altri metodi di cui |
| | | non abbiamo parlato. Il prossimo codice ne usa una |
| | | buona parte per creare un rudimentale editor, di |
| | | nome Tiny Editor.::
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | | def createMenuVoice(self, iconPath, name, |
| | | shortcut, tip, slot):
|
| | | voice = QtGui.QAction(QtGui.QIcon( |
| | | iconPath), name, self)
|
| | | voice.setShortcut(shortcut)
|
| | | voice.setStatusTip(tip)
|
| | | self.connect(voice, QtCore.SIGNAL( |
| | | 'triggered()'), slot)
|
| | |
|
| | | return voice
|
| | |
|
| | | def createSeparator(self):
|
| | | sVoice = QtGui.QAction(self)
|
| | | sVoice.setSeparator(True)
|
| | |
|
| | | return sVoice
|
| | |
|
| | | def createMenu(self):
|
| | | tinyMenu = self.menuBar()
|
| | |
|
| | | file = tinyMenu.addMenu("&File")
|
| | | edit = tinyMenu.addMenu("&Edit")
|
| | | font = tinyMenu.addMenu("F&ont")
|
| | |
|
| | | new = self.createMenuVoice("icons/ |
| | | new.png", "New", "Ctrl+N", "New file", self.textEd |
| | | it.clear)
|
| | | open = self.createMenuVoice("icons |
| | | /open.png", "Open file", "Ctrl+O", "Open a new fil |
| | | e", self.openNewFile)
|
| | | save = self.createMenuVoice("icons |
| | | /save.png", "Save file", "Ctrl+S", "Save file", se |
| | | lf.saveNewFile)
|
| | | sep = self.createSeparator()
|
| | | quit = self.createMenuVoice("icons |
| | | /quit.png", "Quit", "Ctrl+Q", "Quit TinyEditor", Q |
| | | tCore.SLOT('close()'))
|
| | | file.addAction(new)
|
| | | file.addAction(open)
|
| | | file.addAction(save)
|
| | | file.addAction(sep)
|
| | | file.addAction(quit)
|
| | |
|
| | | undo = self.createMenuVoice("icons |
| | | /undo.png", "Undo", "Ctrl+U", "Undo operation", se |
| | | lf.textEdit.undo)
|
| | | redo = self.createMenuVoice("icons |
| | | /redo.png", "Redo", "Ctrl+R", "Redo operation", se |
| | | lf.textEdit.redo)
|
| | | sep1 = self.createSeparator()
|
| | | cut = self.createMenuVoice("icons/ |
| | | cut.png", "Cut", "Ctrl+X", "Cut selected text", se |
| | | lf.textEdit.cut)
|
| | | copy = self.createMenuVoice("icons |
| | | /copy.png", "Copy", "Ctrl+C", "Copy selected text" |
| | | , self.textEdit.copy)
|
| | | paste = self.createMenuVoice("icon |
| | | s/paste.png", "Paste", "Ctrl+V", "Paste text", sel |
| | | f.paste)
|
| | | sep2 = self.createSeparator()
|
| | | selectAll = self.createMenuVoice(" |
| | | icons/selectAll.png", "Select all", "Ctrl+A", "Sel |
| | | ect all text", self.textEdit.selectAll)
|
| | | edit.addAction(undo)
|
| | | edit.addAction(redo)
|
| | | edit.addAction(sep1)
|
| | | edit.addAction(cut)
|
| | | edit.addAction(copy)
|
| | | edit.addAction(paste)
|
| | | edit.addAction(sep2)
|
| | | edit.addAction(selectAll)
|
| | |
|
| | | setFont = self.createMenuVoice("ic |
| | | ons/setfont.png", "Set font", "Ctrl+F", "Set font" |
| | | , self.setFont)
|
| | | underline = self.createMenuVoice(" |
| | | icons/underline.png", "Underline", "Ctrl+L", "Unde |
| | | rline text", self.underline)
|
| | | italic = self.createMenuVoice("ico |
| | | ns/italic.png", "Italic", "Ctrl+I", "Set text to i |
| | | talic", self.italic)
|
| | | tColor = self.createMenuVoice("ico |
| | | ns/color.png", "Set text color", "Ctrl+R", "Set te |
| | | xt color", self.setColor)
|
| | | delete = self.createMenuVoice("ico |
| | | ns/delete.png", "Delete format", "Ctrl+D", "Delete |
| | | format", self.deleteFormat)
|
| | | font.addAction(setFont)
|
| | | font.addAction(underline)
|
| | | font.addAction(italic)
|
| | | font.addAction(tColor)
|
| | | font.addAction(delete)
|
| | |
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | |
|
| | | self.setWindowTitle('Tiny editor') |
| | |
|
| | |
|
| | | self.textEdit = QtGui.QTextEdit()
|
| | | self.textEdit.setReadOnly(False)
|
| | |
|
| | | if self.textEdit.isUndoRedoEnabled |
| | | () == False:
|
| | | self.textEdit.setUndoRedoE |
| | | nabled(True)
|
| | |
|
| | | self.createMenu()
|
| | | self.statusBar()
|
| | | self.setCentralWidget(self.textEdi |
| | | t)
|
| | |
|
| | | def openNewFile(self):
|
| | | fName = QtGui.QFileDialog.getOpenF |
| | | ileName(self, "Open text file", "Open new file", s |
| | | elf.tr("Text Files (*.txt)"))
|
| | |
|
| | | if fName.isEmpty() == False:
|
| | | fptr = open(fName, 'r')
|
| | |
|
| | | content = fptr.read()
|
| | | self.textEdit.append(conte |
| | | nt)
|
| | | fptr.close()
|
| | |
|
| | | def saveNewFile(self):
|
| | | fName = QtGui.QFileDialog.getSaveF |
| | | ileName(self, "Save text file", "Save a new file", |
| | | self.tr("Text Files (*.txt)"))
|
| | |
|
| | | if fName.isEmpty() == False:
|
| | | fptr = open(fName, 'w')
|
| | |
|
| | | fptr.write(self.textEdit.t |
| | | oPlainText())
|
| | | fptr.close()
|
| | |
|
| | | def paste(self):
|
| | | if self.textEdit.canPaste():
|
| | | self.textEdit.paste()
|
| | | else:
|
| | | QtGui.QMessageBox.critical |
| | | (self, "Error", "Impossible to paste text", QtGui. |
| | | QMessageBox.Ok)
|
| | |
|
| | |
|
| | | def setFont(self):
|
| | | font, ok = QtGui.QFontDialog.getFo |
| | | nt()
|
| | |
|
| | | if ok:
|
| | | self.textEdit.setFont(font |
| | | )
|
| | |
|
| | | def underline(self):
|
| | | self.textEdit.setFontUnderline(Tru |
| | | e)
|
| | |
|
| | | def italic(self):
|
| | | self.textEdit.setFontItalic(True)
|
| | |
|
| | | def setColor(self):
|
| | | color = QtGui.QColorDialog.getColo |
| | | r(QtCore.Qt.blue, self)
|
| | |
|
| | | if color.isValid():
|
| | | self.textEdit.setTextColor |
| | | (color)
|
| | |
|
| | | def deleteFormat(self):
|
| | | self.textEdit.setFontUnderline(Fal |
| | | se)
|
| | | self.textEdit.setFontItalic(False) |
| | |
|
| | | self.textEdit.setTextColor(QtCore. |
| | | Qt.black)
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | .. img:: 14
|
| | | :nolink:
|
| | |
|
| | | Il tutto è piuttosto intuitivo.
|
| | | Come notate, la maggior parte delle azioni tipiche |
| | | di un editor (taglia, copia, incolla, seleziona t |
| | | utto, annulla operazione...) non hanno bisogno di |
| | | un'implementazione a parte del programmatore, ma c |
| | | i si può avvalere dei metodi predefiniti del widge |
| | | t.
|
| | | Come noterete, sono riapparsi anche precedenti dia |
| | | log predefiniti.
|
| | | Come esercizio potreste tentare di migliorare ques |
| | | to editor!
|
| | |
|
| | | GroupBox e SpinBox
|
| | | ===================
|
| | |
|
| | | Vediamo altri due widgets utili: GroupBox e Spin |
| | | Box. Il primo serve a dividere diverse sezioni di |
| | | programma tramite dei titoletti in “grassetto”, me |
| | | ntre la seconda è utile per l'input di dati numeri |
| | | ci.::
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | |
|
| | | self.resize(350, 250)
|
| | | self.setWindowTitle('GroupBox e Sp |
| | | inBox')
|
| | |
|
| | | widget = QtGui.QWidget(self)
|
| | |
|
| | | self.gBox = QtGui.QGroupBox("SpinB |
| | | oxes", widget)
|
| | | self.gBox.setCheckable(True)
|
| | | self.gBox.setChecked(True)
|
| | | self.connect(self.gBox, QtCore.SIG |
| | | NAL('clicked()'), self.showSpin)
|
| | |
|
| | | self.iSpin = QtGui.QSpinBox(widget |
| | | )
|
| | | self.iSpin.setRange(0, 100)
|
| | | self.iSpin.setSuffix("%")
|
| | | self.iSpin.setValue(50)
|
| | | self.iSpin.setSingleStep(5)
|
| | |
|
| | | self.dSpin = QtGui.QDoubleSpinBox( |
| | | widget)
|
| | | self.dSpin.setDecimals(3)
|
| | | self.dSpin.setPrefix("$")
|
| | | self.dSpin.setRange(0, 1000.0)
|
| | | self.dSpin.setSingleStep(0.5)
|
| | | self.dSpin.setValue(100)
|
| | |
|
| | | vBox = QtGui.QVBoxLayout(widget)
|
| | | vBox.setSpacing(3)
|
| | |
|
| | | vBox.addWidget(self.iSpin)
|
| | | vBox.addWidget(self.dSpin)
|
| | |
|
| | | widget.setLayout(vBox)
|
| | | self.setCentralWidget(widget)
|
| | |
|
| | | def showSpin(self):
|
| | | if self.gBox.isChecked():
|
| | | self.dSpin.show()
|
| | | self.iSpin.show()
|
| | | else:
|
| | | self.dSpin.hide()
|
| | | self.iSpin.hide()
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | .. img:: 11
|
| | | :nolink:
|
| | |
|
| | | In questo caso, associamo alla GroupBox una checkb |
| | | ox che ci permette di decidere fra due comportamen |
| | | ti. In realtà una GroupBox di default appare solo |
| | | come un titoletto in grassetto, senza alcuna check |
| | | box. Quando si cambia lo stato della checkbox vien |
| | | e emesso un segnale *clicked()*.::
|
| | |
|
| | | if self.gBox.isChecked():
|
| | |
|
| | | Se questo metodo ritorna True, la checkbox è stata |
| | | attivata, altrimenti è stata disattivata.
|
| | | Come vediamo, esistono due principali tipi di spin |
| | | box: la classica *QSpinBox*, che contiene interi, |
| | | e la *QDoubleSpinBox*, che contiene valori double. |
| | |
|
| | | È possibile specificare un range di valori accetta |
| | | bili, un valore di default, il “salto” fra due val |
| | | ori contigui, e stringhe da usare come suffissi o |
| | | prefissi dei valori numerici.
|
| | |
|
| | | ProgressBar
|
| | | ============
|
| | | Esempio di utilizzo di una barra di avanzamento.:: |
| | |
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | |
|
| | | self.resize(350, 250)
|
| | | self.setWindowTitle('ProgressBar') |
| | |
|
| | | widget = QtGui.QWidget()
|
| | |
|
| | | grid = QtGui.QGridLayout(widget)
|
| | | self.progressBar = QtGui.QProgress |
| | | Bar(widget)
|
| | | self.progressBar.setRange(0, 100)
|
| | | self.progressBar.setValue(0)
|
| | | self.progressBar.setTextVisible(Tr |
| | | ue)
|
| | |
|
| | | self.button = QtGui.QPushButton('S |
| | | tart', widget)
|
| | | self.connect(self.button, QtCore.S |
| | | IGNAL('clicked()'), self.StartProgress)
|
| | |
|
| | | self.horiz = QtGui.QPushButton('Ve |
| | | rtical', widget)
|
| | | self.horiz.setCheckable(True)
|
| | | self.connect(self.horiz, QtCore.SI |
| | | GNAL('clicked()'), self.changeOrientation)
|
| | |
|
| | | self.direction = QtGui.QPushButton |
| | | ('Reverse', widget)
|
| | | self.direction.setCheckable(True)
|
| | | self.connect(self.direction, QtCor |
| | | e.SIGNAL('clicked()'), self.Reverse)
|
| | |
|
| | | grid.addWidget(self.progressBar, 0 |
| | | , 0, 1, 3)
|
| | | grid.addWidget(self.button, 1, 0)
|
| | | grid.addWidget(self.horiz, 1, 1)
|
| | | grid.addWidget(self.direction, 1, |
| | | 2)
|
| | |
|
| | | self.timer = QtCore.QBasicTimer()
|
| | | self.step = 0
|
| | |
|
| | | widget.setLayout(grid)
|
| | | self.setCentralWidget(widget)
|
| | |
|
| | | def Reverse(self):
|
| | | if self.direction.isChecked():
|
| | | self.progressBar.setInvert |
| | | edAppearance(True)
|
| | | else:
|
| | | self.progressBar.setInvert |
| | | edAppearance(False)
|
| | |
|
| | | def changeOrientation(self):
|
| | | if self.horiz.isChecked():
|
| | | self.progressBar.setOrient |
| | | ation(QtCore.Qt.Vertical)
|
| | | else:
|
| | | self.progressBar.setOrient |
| | | ation(QtCore.Qt.Horizontal)
|
| | |
|
| | | def timerEvent(self, event):
|
| | | if self.step >= 100:
|
| | | self.timer.stop()
|
| | | return
|
| | | self.step = self.step+1
|
| | | self.progressBar.setValue(self.ste |
| | | p)
|
| | |
|
| | | def StartProgress(self):
|
| | | if self.timer.isActive():
|
| | | self.timer.stop()
|
| | | self.button.setText('Start |
| | | ')
|
| | | else:
|
| | | self.timer.start(100, self |
| | | )
|
| | | self.button.setText('Stop' |
| | | )
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | .. img:: 13
|
| | | :nolink:
|
| | |
|
| | | La dichiarazione della progress bar è questa:::
|
| | |
|
| | | self.progressBar = QtGui.QProgress |
| | | Bar(widget)
|
| | | self.progressBar.setRange(0, 100)
|
| | | self.progressBar.setValue(0)
|
| | | self.progressBar.setTextVisible(Tr |
| | | ue)
|
| | |
|
| | | Nota: i tre metodi che chiamo dopo il costruttore |
| | | in realtà potrebbero essere omessi, in quanto quel |
| | | li specificati sono già i comportamenti di default |
| | | . Li ho inseriti solamente a scopo dimostrativo.:: |
| | |
|
| | |
|
| | | self.timer = QtCore.QBasicTimer()
|
| | | self.step = 0
|
| | |
|
| | | Qui dichiariamo un timer, un oggetto di basso live |
| | | llo molto semplice e adatto alle nostre esigenze. |
| | | Ogni tot millisecondi (il valore precisato nel met |
| | | odo *start()*), il timer genera un evento che noi |
| | | intercettiamo con la nostra funzione. Ogni 100 mil |
| | | lisecondi dunque avanziamo di 1 nella progress bar |
| | | .
|
| | | Se vogliamo che essa sia più veloce, dobbiamo ovvi |
| | | amente diminuire il valore numerico passato a *sta |
| | | rt()*.
|
| | | Le due funzioni importanti sono *Reverse* e *chang |
| | | eOrientation*: essi, a seconda del valore del togg |
| | | le button corrispondente, “rovesciano” il testo de |
| | | lla progress bar oppure il suo orientamento.
|
| | |
|
| | | Tooltip, password e combo box
|
| | | ==============================
|
| | |
|
| | | Finiamo con tre widget.::
|
| | |
|
| | | #!/usr/bin/python
|
| | |
|
| | | import sys
|
| | | from PyQt4 import QtGui, QtCore
|
| | |
|
| | | class MainWindow(QtGui.QMainWindow):
|
| | | def __init__(self):
|
| | | QtGui.QMainWindow.__init__(self)
|
| | |
|
| | | self.resize(350, 250)
|
| | | self.setWindowTitle('Tooltip e pas |
| | | sword')
|
| | | widget = QtGui.QWidget()
|
| | | hbox = QtGui.QHBoxLayout(widget)
|
| | | hbox.setSpacing(10)
|
| | |
|
| | | self.label = QtGui.QLabel("Enter y |
| | | our username", widget)
|
| | | self.line = QtGui.QLineEdit(widget |
| | | )
|
| | | comboBox = QtGui.QComboBox()
|
| | | comboBox.addItem("Username")
|
| | | comboBox.addItem("Password")
|
| | | self.connect(comboBox, QtCore.SIGN |
| | | AL("activated(int)"), self.changeEcho)
|
| | |
|
| | | hbox.addWidget(self.label)
|
| | | hbox.addWidget(self.line)
|
| | | hbox.addWidget(comboBox)
|
| | | self.setToolTip('This is a tooltip |
| | | ')
|
| | | self.setCentralWidget(widget)
|
| | |
|
| | | def changeEcho(self, index):
|
| | | if index == 0:
|
| | | self.line.setEchoMode(QtGu |
| | | i.QLineEdit.Normal)
|
| | | self.label.setText("Enter |
| | | your username")
|
| | | else:
|
| | | self.line.setEchoMode(QtGu |
| | | i.QLineEdit.Password)
|
| | | self.label.setText("Enter |
| | | your password")
|
| | |
|
| | | app = QtGui.QApplication(sys.argv)
|
| | | main = MainWindow()
|
| | | main.show()
|
| | | sys.exit(app.exec_())
|
| | |
|
| | | .. img:: 16
|
| | | :nolink:
|
| | |
|
| | | Il widget *QLineEdit* è comodo per inserire piccol |
| | | e porzioni di testo. Se vogliamo una maggiore sicu |
| | | rezza possiamo anche impostare il tipo di “echo” a |
| | | password, come viene fatto nello slot.
|
| | | La *combo box* permette all'utente di scegliere di |
| | | verse opzioni: la selezione è catturata dal segnal |
| | | e *activated()*, che manda al proprio slot un para |
| | | metro intero, ovvero l'indice della voce momentane |
| | | amente attivata.
|
| | | Il tooltip può essere visto soffermando il cursore |
| | | su un punto qualsiasi della finestra.
|
| | |
|
| | | Conclusioni.
|
| | | #############
|
| | |
|
| | | Se avete qualsiasi suggerimento, correzione ai cod |
| | | ici, miglioria che volete vedere in questo tutoria |
| | | l, scrivetemi pure a syn.shainer@gmail.com
|
| | | Lisa |