Hlavní navigace

Práce s textem v PyQt4

Jan Kaluža

V dnešním článku ze série o knihovně PyQt4 se naučíme editovat text s pomocí QTextEdit, používat ikony pomocí třídy QIcon a vytvářet roletová menu s QComboBox. Opět si vše předvedeme na praktických příkladech. Společně si vytvoříme například jednoduchý prohlížeč textových souborů.

QTextEdit

QTextEdit slouží k zobrazení nebo editování víceřádkového textu. Text může být formátován pomocí HTML nebo zobrazen jako PlainText (čístý text) bez jakéhokoliv formátování.

QTextEdit ( text, parent )
QTextEdit ( parent )

Funkce vytvoří nový QTextEdit. Parametr parent je rodičem QTextEditu a parametr text je jeho obsah. Druhá syntaxe umožňuje vytvořit prázdný QTextEdit.

QTextEdit.set­ReadOnly ( bool )

Pokud je hodnota proměnné bool True, nebude umožněno editování textu, ale pouze jeho zobrazení.

QTextEdit.setHtml ( text )

Touto funkcí nastavíme text, který QTextEdit zobrazí. Funkci používáme v případě textu formátovaného pomocí HTML. Můžeme pomocí ni zobrazi i čistý, ale musíme při tom pamatovat, že například znaky < a > budou chápány jako znaky HTML a může se tak celý text rozhodit.

QTextEdit.toHtml ( )

Funkce vrátí aktuální text v QTextEditu ve formátu HTML.

QTextEdit.set­PlainText ( text )

Funkce nastavuje text QTextEditu. HTML syntaxe nemá v tomto případě v textu žádný význam.

QTextEdit.toPla­inText ( )

Funkce vrátí text, který QTextEdit obsahuje, bez HTML značek.

QTextEdit.set­FontItalic ( bool )

Touto funkcí určíme, zda bude písmo zobrazeno kurzívou nebo ne. Pokud je hodnota proměnné bool True, je kurzíva použita.

QTextEdit.set­FontUnderline ( bool )

Pokud je proměnná bool hodnoty True, bude text podtržený.

QTextEdit.set­FontWeight ( weight )

Funkcí nastavujeme velikost písma textu zadávaného do QTextEditu. Proměnná weight je typu integer.

QTextEdit.cur­sorPositionChan­ged () – signál

Tento signál je generován, pokud dojde ke změně pozice kursoru v QTextEditu.

QTextEdit.tex­tChanged () – signál

Tento signál je generován, pokud je změněn text v QTextEditu.

QTextEdit – Praxe

PyQt 4 1

V praktické části vytvoříme skript pro prohlížení textových souborů. Skládat se bude z QLineEditu fileNameLineEdit, do kterého uživatel zadá cestu k souboru, který chce otevřít. Samotné jeho otevření proběhne po kliknutí na tlačítko showPushButton, jehož signál clicked() je napojen na funkci showFile(). Funkce showFile() otevře zadaný soubor, načte jeho obsah a zobrazí jej v QTextEditu mainTextEdit.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys

def showFile():
    """ Otevreni souboru a vlozeni jeho obsahu do QTextEditu """
    f=open(str(fileNameLineEdit.text()))
    text=f.read()
    # Obsah souboru vlozime do widgetu mainTextEdit
    mainTextEdit.setPlainText(text)
    f.close()

app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.setWindowTitle("QTextEdit")
mainWidget=QtGui.QWidget(mainWindow)
mainWindow.setCentralWidget(mainWidget)
layout=QtGui.QGridLayout(mainWidget)

headerLabel=QtGui.QLabel(u"<h1>Prohlížeč souborů</h1>",mainWidget)
headerLabel.setAlignment(QtCore.Qt.AlignHCenter)

fileNameLabel=QtGui.QLabel("Soubor:",mainWidget)
fileNameLineEdit=QtGui.QLineEdit(mainWidget)

# Vytvorime QTextEdit mainTextEdit
mainTextEdit=QtGui.QTextEdit(mainWidget)
# Nastavime jej jen pro cteni
mainTextEdit.setReadOnly(True)

showPushButton=QtGui.QPushButton(u"Zobrazit",mainWidget)
closePushButton=QtGui.QPushButton(u"Zavřít",mainWidget)

# Pridame objekty do layoutu
layout.addWidget(headerLabel,0,0,1,2)
layout.addWidget(fileNameLabel,1,0)
layout.addWidget(fileNameLineEdit,1,1)
layout.addWidget(mainTextEdit,2,0,1,2)
layout.addWidget(showPushButton,3,0)
layout.addWidget(closePushButton,3,1)

# napojime signaly tlacitek
app.connect(closePushButton,QtCore.SIGNAL("clicked ()"),mainWindow.close)
app.connect(showPushButton,QtCore.SIGNAL("clicked ()"),showFile)

mainWindow.show()
sys.exit(app.exec_())

QComboBox – Teorie

QComboBox je rozbalovací tlačítko, které umožňuje vybrat jednu položku ze seznamu. Pokud jej nastavíme jako editovatelný, může uživatel přímo přidávat nové položky. Každá položka může mít kromě textu i svou ikonu nebo data.

QComboBox ( parent ) – modul QtGui

Jednou z těchto funkcí můžeme QComboBox vytvořit. Parametr parent je rodičem QComboBoxu.

QComboBox.addItem ( text, data = QVariant() )

Funkce addItem přidá do QComboBoxu novou položku. Proměnná text je text položky. Proměnná data je nepovinná proměnná vytvořena funkcí QVariant(). Používá se v případě, kdy chceme k položce přiřadit ještě nějaká data. Například pokud chceme, aby text položky byl jménem člověka, ale potřebujeme také znát jeho rodné číslo, uložíme ho do proměnné data. Více o funkci QVariant() si řekneme níže v článku.

QComboBox.addItem ( icon, text, data = QVariant() )

Tato funkce je stejná jako funkce předchozí s tím rozdílem, že přiřadí položce ikonu icon. Proměnná icon je vytvořena funkcí QIcon(), o které si povíme v další části článku.

QComboBox.itemData ( index )

Funkce vrací data položky, která je uložena v QComboBoxu pod číslem index. Vrácená data jsou ve formátu QVariant.

QComboBox.clear ( )

Funkce clear smaže z QComboBoxu všechny položky.

QComboBox.curren­tIndex ( )

Funkce vrací číslo vybrané položky.

QComboBox.curren­tText ( )

Funkce vrací text vybrané položky.

QComboBox.itemText (index)

Funkce vrací text položky uložené pod číslem index.

QComboBox.setE­ditable(bool)

Touto funkcí můžeme nastavit QComboBox jako editovatelný. Pokud je QComboBox nastaven jako editovatelný (bool má hodnotu True), může uživatel přidávát nové položky (podobným způsobem, jako do QLineEditu).

QComboBox.setAu­toCompletion ( bool )

Pokud je hodnota proměnné bool True a QComboBox je editovatelný, je povoleno automatické doplňování v textu.

QComboBox.count ( )

Funkce count vrací počet položek v QComboBoxu.

QComboBox.hig­hlighted (int) – signál
QComboBox.hig­hlighted (const QString&) – signál

Signály highlighted(int) a highlighted(const QString&) jsou generovány, pokud uživatel označí položku v seznamu QComboBoxu. Funkci, na kterou je signál napojen, je předáno číslo položky (v případě prvního signálu) nebo text položky (v případě druhého signálu).

QComboBox.activated (int) – signál
QComboBox.activated (const QString&) – signál

Signály activated(int) a activated(const QString&) jsou generovány, pokud uživatel vybere ze seznamu položku. Funkci, na kterou je signál napojen, je opět předáno číslo položky (v případě prvního signálu) nebo text položky (v případě druhého signálu). V případě, že je QComboBox nastaven jako editovatelný, je tento signál generován i při stisku klávesy enter.

QComboBox – Praxe

PyQt 4 2

Vylepšíme předchozí skript tím, že místo QLineEditu použijeme QComboBox fileNameComboBox, který bude nastaven jako editovatelný. Získáme tak jednoduchou historii otevřených souborů. Pokud je text ve fileNameComboBoxu potvrzen klávesou enter, je spuštěna funkce showFile() a je jí předán zadaný text (název souboru). Pak již vše probíhá jako v předchozím příkladu. Další příklady použítí QComboBoxu můžete vidět dále v článku v částech o QIcon a QVariant.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys

def showFile(file):
    """ Otevreni souboru a vlozeni jeho obsahu do QTextEditu """
    f=open(str(file))
    text=f.read()
    mainTextEdit.setPlainText(text)
    f.close()

app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.setWindowTitle("QComboBox")
mainWidget=QtGui.QWidget(mainWindow)
mainWindow.setCentralWidget(mainWidget)
layout=QtGui.QGridLayout(mainWidget)

headerLabel=QtGui.QLabel(u"<h1>Prohlížeč souborů</h1>",mainWidget)
headerLabel.setAlignment(QtCore.Qt.AlignHCenter)

fileNameLabel=QtGui.QLabel("Soubor:",mainWidget)
# Vytvorime QComboBox
fileNameComboBox=QtGui.QComboBox(mainWidget)
# Nastavime ho editovatelnym
fileNameComboBox.setEditable(True)
# Povolime automaticke doplnovani
fileNameComboBox.setAutoCompletion(True)

mainTextEdit=QtGui.QTextEdit(mainWidget)
mainTextEdit.setReadOnly(True)

closePushButton=QtGui.QPushButton(u"Zavřít",mainWidget)

# Pridame objekty do layoutu
layout.addWidget(headerLabel,0,0,1,2)
layout.addWidget(fileNameLabel,1,0)
layout.addWidget(fileNameComboBox,1,1)
layout.addWidget(mainTextEdit,2,0,1,2)
layout.addWidget(closePushButton,3,1)

app.connect(closePushButton,QtCore.SIGNAL("clicked ()"),mainWindow.close)
# Pokud je generovan signal activated (const QString&), je spustena fce showFile
# a je ji predan text aktualni polozky v fileNameComboBoxu
app.connect(fileNameComboBox,QtCore.SIGNAL("activated (const QString&)"),showFile)

mainWindow.show()
sys.exit(app.exec_())

QVariant – Teorie

QVariant je třída, která „převádí“ různé datové typy na typ QVariant.

QVariant ( data ) – modul QtCore

Funkce vytvoří QVariant. Parametr data může být v podstatě jakéhokoliv typu a je převeden na QVariant.

QVariant.toString ( )

Převede obsah QVariantu na string (text).

QVariant.toInt ( )

Převede obsah QVariantu na int (celé číslo).

QVariant.toDouble ( )

Převede obsah QVariantu na float (desetinné číslo).

QVariant.toBool ( )

Převede obsah QVariantu na typ boolean.

QVariant – Praxe

PyQt 4 3

QVariant si v praxi ukážeme na jednoduchém příkladu. Představme si již zmiňovaný případ s lidmi v QComboBox seznamu. Chceme zobrazit pouze jejich jméno, ale u každého jména chceme mít uložené i rodné číslo. Docílit toho můžeme například tímto skriptem:

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys

def activated(i):
    # vyzadame si data polozky jako QVariant
    data=programsComboBox.itemData(i)
    # prevedeme QVariant na text a zobrazime
    label.setText("Rodne cislo: "+data.toString())

app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.setWindowTitle("QVariant")
mainWidget=QtGui.QWidget(mainWindow)
mainWindow.setCentralWidget(mainWidget)
layout=QtGui.QVBoxLayout(mainWidget)

label=QtGui.QLabel("Rodne cislo: ",mainWidget)

programsComboBox=QtGui.QComboBox(mainWidget)
# Jako data polozky ulozime QVariant vytvoreny z rodneho cisla
programsComboBox.addItem("Jan Novak",QtCore.QVariant("661107/3939"))
programsComboBox.addItem("Jakub Dvorak",QtCore.QVariant("750802/1278"))

# Pridame objekty do layoutu
layout.addWidget(programsComboBox)
layout.addWidget(label)

app.connect(programsComboBox,QtCore.SIGNAL("activated (int)"),activated)
mainWindow.show()
sys.exit(app.exec_())

QIcon – Teorie

V části o QComboBoxu jsme si řekli, že QComboBox může přiřadit ke každé položce ikonu. Tato ikona je vytvořena pomocí třídy QIcon, která je podobná třídě QPixmap, o které jsme si řekli v minulém díle.

QIcon () – modul QtGui

Touto funkcí vytvoříme prázdný QICon.

QIcon ( pixmap )

Touto funkcí vytvoříme QIcon z existujícího QPixmapu.

QIcon ( fileName )

Podobně jako QPixmap má i QIcon možnosti načíst obrázek ze souboru. Stejně jako u QPixmap nekontroluje QIcon existenci souboru zadaného proměnnou fileName.

QIcon.addFile ( fileName )

Funkce addFile načítá do QIcon obrázek ze souboru. Proměnná fileName je cestou k souboru.

QIcon.addPixmap ( pixmap )

Funkce addPixmap načítá do QIcon obrázek typu QPixmap.

QIcon a ostatní widgety

V této části se naučíme používat třídu QIcon s ostatními widgety, o kterých jsme se bavili v minulých dílech.

QMainWindow.set­WindowIcon ( icon )

Touto funkcí nastavíme hlavnímu oknu ikonu icon.

QPushButton.setIcon ( icon )

Touto funkcí přiřadíme tlačítku QPushButton ikonu icon.

QIcon – Praxe

PyQt 4 4

Vylepšíme příklad QVariantu o ikonky jednotlivých jmen a ikonu hlavního okna. Práce s QIcon je velmi podobná práci s QPixmap.

#!/usr/bin/env python
# -*- coding: utf-8 -*-
from PyQt4 import QtCore, QtGui
import sys

def activated(i):
    data=programsComboBox.itemData(i)
    label.setText("Rodne cislo: "+data.toString())

app = QtGui.QApplication(sys.argv)
mainWindow = QtGui.QMainWindow()
mainWindow.setWindowTitle("QIcon")

# Nastavime ikonu hlavniho okna
mainWindow.setWindowIcon(QtGui.QIcon("clock.png"))

mainWidget=QtGui.QWidget(mainWindow)
mainWindow.setCentralWidget(mainWidget)
layout=QtGui.QVBoxLayout(mainWidget)

label=QtGui.QLabel("Rodne cislo: ",mainWidget)

programsComboBox=QtGui.QComboBox(mainWidget)
# Pridame polozky programsComboBoxu s ikonou bell.png
programsComboBox.addItem(QtGui.QIcon("bell.png"),"Jan Novak",QtCore.QVariant("661107/3939"))
programsComboBox.addItem(QtGui.QIcon("bell.png"),"Jakub Dvorak",QtCore.QVariant("750802/1278"))

# Pridame objekty do layoutu
layout.addWidget(programsComboBox)
layout.addWidget(label)

app.connect(programsComboBox,QtCore.SIGNAL("activated (int)"),activated)
mainWindow.show()
sys.exit(app.exec_())

Závěr

V dalším díle se naučíme pracovat s zaškrtávacími poli a s widgetem QListView, který umožňuje zobrazovat seznam mnoha položek.

Našli jste v článku chybu?

30. 4. 2012 12:03

miso (neregistrovaný)

Zdravim,
ten priklad s ComboBox.addI­tem(str, QVariant) mi pod py2 funguje, ale pod py3 skonci s chybou:

Traceback (most recent call last):
File "./test3.py", line 23, in <module>
programsCombo­Box.addItem("Jan Novak",QtCore­.QVariant("661107/39­39"))
TypeError: PyQt4.QtCore.QVa­riant represents a mapped type and cannot be instantiated

Cim to je sposobne, ako upravit ten kod, aby to fungovalo?
Dakujem






5. 2. 2007 0:25

standa (neregistrovaný)
Aha. Dobre vedet. :) Ale stejne, C++ forever. :)
Vitalia.cz: Jmenuje se Janina a žije bez cukru

Jmenuje se Janina a žije bez cukru

Lupa.cz: Kdo pochopí vtip, může jít do ČT vyvíjet weby

Kdo pochopí vtip, může jít do ČT vyvíjet weby

Lupa.cz: Teletext je „internetem hipsterů“

Teletext je „internetem hipsterů“

Podnikatel.cz: K EET. Štamgast už peníze na stole nenechá

K EET. Štamgast už peníze na stole nenechá

Podnikatel.cz: Změny v cestovních náhradách 2017

Změny v cestovních náhradách 2017

DigiZone.cz: Rádio Šlágr má licenci pro digi vysílání

Rádio Šlágr má licenci pro digi vysílání

Vitalia.cz: Potvrzeno: Pobyt v lese je skvělý na imunitu

Potvrzeno: Pobyt v lese je skvělý na imunitu

Měšec.cz: Jak vymáhat výživné zadarmo?

Jak vymáhat výživné zadarmo?

120na80.cz: Co všechno ovlivňuje ženskou plodnost?

Co všechno ovlivňuje ženskou plodnost?

DigiZone.cz: Recenze Westworld: zavraždit a...

Recenze Westworld: zavraždit a...

Lupa.cz: Co se dá měřit přes Internet věcí

Co se dá měřit přes Internet věcí

Měšec.cz: Kdy vám stát dá na stěhování 50 000 Kč?

Kdy vám stát dá na stěhování 50 000 Kč?

Měšec.cz: Jak levně odeslat balík přímo z domu?

Jak levně odeslat balík přímo z domu?

Vitalia.cz: Jsou čajové sáčky toxické?

Jsou čajové sáčky toxické?

Lupa.cz: Proč firmy málo chrání data? Chovají se logicky

Proč firmy málo chrání data? Chovají se logicky

Lupa.cz: Propustili je z Avastu, už po nich sahá ESET

Propustili je z Avastu, už po nich sahá ESET

Lupa.cz: Insolvenční řízení kvůli cookies? Vítejte v ČR

Insolvenční řízení kvůli cookies? Vítejte v ČR

Podnikatel.cz: Podnikatelům dorazí varování od BSA

Podnikatelům dorazí varování od BSA

120na80.cz: Horní cesty dýchací. Zkuste fytofarmaka

Horní cesty dýchací. Zkuste fytofarmaka

Měšec.cz: Zdravotní a sociální pojištění 2017: Připlatíte

Zdravotní a sociální pojištění 2017: Připlatíte