100% found this document useful (5 votes)
54 views

Instant ebooks textbook Modern PyQt: Create GUI Applications for Project Management, Computer Vision, and Data Analysis Joshua Willman download all chapters

Joshua

Uploaded by

loyeddilipl9
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (5 votes)
54 views

Instant ebooks textbook Modern PyQt: Create GUI Applications for Project Management, Computer Vision, and Data Analysis Joshua Willman download all chapters

Joshua

Uploaded by

loyeddilipl9
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 55

Download the Full Version of textbook for Fast Typing at textbookfull.

com

Modern PyQt: Create GUI Applications for Project


Management, Computer Vision, and Data Analysis
Joshua Willman

https://textbookfull.com/product/modern-pyqt-create-gui-
applications-for-project-management-computer-vision-and-
data-analysis-joshua-willman/

OR CLICK BUTTON

DOWNLOAD NOW

Download More textbook Instantly Today - Get Yours Now at textbookfull.com


Recommended digital products (PDF, EPUB, MOBI) that
you can download immediately if you are interested.

Modern PyQt Create GUI Applications for Project Management


Computer Vision and Data Analysis 1st Edition Joshua
Willman
https://textbookfull.com/product/modern-pyqt-create-gui-applications-
for-project-management-computer-vision-and-data-analysis-1st-edition-
joshua-willman/
textboxfull.com

Beginning PyQt A Hands on Approach to GUI Programming


Willman Joshua M

https://textbookfull.com/product/beginning-pyqt-a-hands-on-approach-
to-gui-programming-willman-joshua-m/

textboxfull.com

Beginning PyQt A Hands on Approach to GUI Programming


Willman Joshua M

https://textbookfull.com/product/beginning-pyqt-a-hands-on-approach-
to-gui-programming-willman-joshua-m-2/

textboxfull.com

Biota Grow 2C gather 2C cook Loucas

https://textbookfull.com/product/biota-grow-2c-gather-2c-cook-loucas/

textboxfull.com
Beginning PyQt: A Hands-on Approach to GUI Programming 1st
Edition Joshua Willman

https://textbookfull.com/product/beginning-pyqt-a-hands-on-approach-
to-gui-programming-1st-edition-joshua-willman/

textboxfull.com

Beginning PyQt: A Hands-on Approach to GUI Programming 1st


Edition Joshua M. Willman

https://textbookfull.com/product/beginning-pyqt-a-hands-on-approach-
to-gui-programming-1st-edition-joshua-m-willman/

textboxfull.com

Create GUI Applications with Python Qt5 PySide2 Edition


Martin Fitzpatrick

https://textbookfull.com/product/create-gui-applications-with-python-
qt5-pyside2-edition-martin-fitzpatrick/

textboxfull.com

Create Gui Applications with Python Qt5 4th Edition Martin


Fitzpack

https://textbookfull.com/product/create-gui-applications-with-python-
qt5-4th-edition-martin-fitzpack/

textboxfull.com

Project Management and BIM for Sustainable Modern Cities


Mohamed Shehata

https://textbookfull.com/product/project-management-and-bim-for-
sustainable-modern-cities-mohamed-shehata/

textboxfull.com
Modern
PyQt
Create GUI Applications for Project
Management, Computer Vision,
and Data Analysis

Joshua Willman
Modern PyQt
Create GUI Applications for Project
Management, Computer Vision,
and Data Analysis

Joshua Willman
Modern PyQt
Joshua Willman
Hampton, VA, USA

ISBN-13 (pbk): 978-1-4842-6602-1 ISBN-13 (electronic): 978-1-4842-6603-8


https://doi.org/10.1007/978-1-4842-6603-8

Copyright © 2021 by Joshua Willman


This work is subject to copyright. All rights are reserved by the Publisher, whether the whole or part of the
material is concerned, specifically the rights of translation, reprinting, reuse of illustrations, recitation,
broadcasting, reproduction on microfilms or in any other physical way, and transmission or information
storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar methodology now
known or hereafter developed.
Trademarked names, logos, and images may appear in this book. Rather than use a trademark symbol with
every occurrence of a trademarked name, logo, or image we use the names, logos, and images only in an
editorial fashion and to the benefit of the trademark owner, with no intention of infringement of the
trademark.
The use in this publication of trade names, trademarks, service marks, and similar terms, even if they are not
identified as such, is not to be taken as an expression of opinion as to whether or not they are subject to
proprietary rights.
While the advice and information in this book are believed to be true and accurate at the date of publication,
neither the authors nor the editors nor the publisher can accept any legal responsibility for any errors or
omissions that may be made. The publisher makes no warranty, express or implied, with respect to the
material contained herein.
Managing Director, Apress Media LLC: Welmoed Spahr
Acquisitions Editor: Celestin Suresh John
Development Editor: Rita Fernando
Coordinating Editor: Divya Modi
Cover designed by eStudioCalamar
Cover image designed by Pixabay
Distributed to the book trade worldwide by Springer Science+Business Media New York, 1 New York Plaza,
Suite 4600, New York, NY 10004-1562, USA. Phone 1-800-SPRINGER, fax (201) 348-4505, e-mail orders-ny@
springer-sbm.com, or visit www.springeronline.com. Apress Media, LLC is a California LLC and the sole
member (owner) is Springer Science + Business Media Finance Inc (SSBM Finance Inc). SSBM Finance Inc
is a Delaware corporation.
For information on translations, please e-mail booktranslations@springernature.com; for reprint,
paperback, or audio rights, please e-mail bookpermissions@springernature.com.
Apress titles may be purchased in bulk for academic, corporate, or promotional use. eBook versions and
licenses are also available for most titles. For more information, reference our Print and eBook Bulk Sales
web page at http://www.apress.com/bulk-sales.
Any source code or other supplementary material referenced by the author in this book is available to
readers on GitHub via the book’s product page, located at www.apress.com/9781484266021. For more
detailed information, please visit http://www.apress.com/source-code.
Printed on acid-free paper
To those who make me laugh

Valorie, Jason, Jazzmin, Teesha, Evelyn, Kalani


Table of Contents
About the Author����������������������������������������������������������������������������������������������������� xi

About the Technical Reviewer������������������������������������������������������������������������������� xiii


Acknowledgments���������������������������������������������������������������������������������������������������xv

Introduction�����������������������������������������������������������������������������������������������������������xvii

Chapter 1: Overview of PyQt5����������������������������������������������������������������������������������� 1


What Is PyQt?�������������������������������������������������������������������������������������������������������������������������������� 2
Installing PyQt5����������������������������������������������������������������������������������������������������������������������� 3
Project 1.1: Pomodoro Timer��������������������������������������������������������������������������������������������������������� 4
Pomodoro Timer Solution�������������������������������������������������������������������������������������������������������������� 6
Explanation���������������������������������������������������������������������������������������������������������������������������� 17
Project 1.2: User Manager Application���������������������������������������������������������������������������������������� 31
User Manager Application Solution��������������������������������������������������������������������������������������������� 32
Explanation���������������������������������������������������������������������������������������������������������������������������� 37
Summary������������������������������������������������������������������������������������������������������������������������������������ 42

Chapter 2: Creating GUIs for Project Management������������������������������������������������� 43


The Basics of Drag and Drop������������������������������������������������������������������������������������������������������ 44
Drag and Drop with PyQt������������������������������������������������������������������������������������������������������� 45
The QDrag and QMimeData Classes�������������������������������������������������������������������������������������� 47
Example 2.1: Drag and Drop Data from Other Sources��������������������������������������������������������������� 48
Explanation���������������������������������������������������������������������������������������������������������������������������� 52
Example 2.2: Drag and Drop Widgets������������������������������������������������������������������������������������������ 54
Explanation���������������������������������������������������������������������������������������������������������������������������� 58
Project 2.1: Project Management GUI����������������������������������������������������������������������������������������� 59

v
Table of Contents

Project Management GUI Solution���������������������������������������������������������������������������������������������� 60


Explanation���������������������������������������������������������������������������������������������������������������������������� 67
Summary������������������������������������������������������������������������������������������������������������������������������������ 72

Chapter 3: Data Visualization and Analysis������������������������������������������������������������ 73


Steps for Data Analysis��������������������������������������������������������������������������������������������������������������� 74
The PyQtChart Module���������������������������������������������������������������������������������������������������������������� 76
Overview of Chart Types�������������������������������������������������������������������������������������������������������� 76
Installing PyQtChart��������������������������������������������������������������������������������������������������������������� 78
Example 3.1: Creating a Simple Chart���������������������������������������������������������������������������������������� 78
Quick Glance at the Dataset�������������������������������������������������������������������������������������������������� 79
Explanation���������������������������������������������������������������������������������������������������������������������������� 83
Project 3.1: Data Visualization GUI���������������������������������������������������������������������������������������������� 86
Quick Glance at the Dataset�������������������������������������������������������������������������������������������������� 86
Data Visualization GUI Solution��������������������������������������������������������������������������������������������������� 88
Explanation���������������������������������������������������������������������������������������������������������������������������� 96
Example 3.2: Combining Different Chart Types������������������������������������������������������������������������� 101
A Brief Introduction to Linear Regression���������������������������������������������������������������������������� 102
Installing NumPy����������������������������������������������������������������������������������������������������������������� 104
Explanation�������������������������������������������������������������������������������������������������������������������������� 108
Project 3.2: Visualizing Data with Matplotlib����������������������������������������������������������������������������� 111
Introduction to Matplotlib���������������������������������������������������������������������������������������������������� 112
Quick Glance at the Dataset������������������������������������������������������������������������������������������������ 113
Visualizing Data with Matplotlib Solution���������������������������������������������������������������������������������� 113
Explanation�������������������������������������������������������������������������������������������������������������������������� 117
Summary���������������������������������������������������������������������������������������������������������������������������������� 122

Chapter 4: Database Handling in PyQt������������������������������������������������������������������ 125


Using SQL with PyQt����������������������������������������������������������������������������������������������������������������� 126
Example 4.1: Creating the Database����������������������������������������������������������������������������������������� 128
Brief Introduction to SQL Commands���������������������������������������������������������������������������������� 129
Explanation�������������������������������������������������������������������������������������������������������������������������� 136

vi
Table of Contents

Example 4.2: Displaying Data with QTableView������������������������������������������������������������������������ 139


Explanation�������������������������������������������������������������������������������������������������������������������������� 143
Project 4.1: SQL Manager GUI��������������������������������������������������������������������������������������������������� 145
SQL Manager GUI Solution�������������������������������������������������������������������������������������������������������� 145
Part 1: The Login Script������������������������������������������������������������������������������������������������������� 146
Part 2: The SQL Manager Script������������������������������������������������������������������������������������������� 153
Summary���������������������������������������������������������������������������������������������������������������������������������� 162

Chapter 5: GUIs for Computer Vision�������������������������������������������������������������������� 163


What Is Computer Vision?��������������������������������������������������������������������������������������������������������� 166
Brief Overview of Digital Images����������������������������������������������������������������������������������������� 166
An Introduction to OpenCV�������������������������������������������������������������������������������������������������������� 168
Installing OpenCV���������������������������������������������������������������������������������������������������������������� 168
Example 5.1: Display Images from OpenCV in PyQt������������������������������������������������������������������ 170
Explanation�������������������������������������������������������������������������������������������������������������������������� 174
Project 5.1: Image Processing GUI�������������������������������������������������������������������������������������������� 178
Image Processing GUI Solution������������������������������������������������������������������������������������������������� 179
Explanation�������������������������������������������������������������������������������������������������������������������������� 186
Example 5.2: Display Videos from OpenCV in PyQt������������������������������������������������������������������� 190
Explanation�������������������������������������������������������������������������������������������������������������������������� 197
Project 5.2: Human Detection and Tracking GUI������������������������������������������������������������������������ 200
Human Detection and Tracking GUI Solution����������������������������������������������������������������������������� 201
Explanation�������������������������������������������������������������������������������������������������������������������������� 206
Summary���������������������������������������������������������������������������������������������������������������������������������� 208

Chapter 6: Visualizing 3D Data����������������������������������������������������������������������������� 209


The PyQtDataVisualization Module������������������������������������������������������������������������������������������� 210
Installing PyQtDataVisualization������������������������������������������������������������������������������������������ 210
Example 6.1: Creating a 3D Bar Graph�������������������������������������������������������������������������������������� 210
Quick Glance at the Dataset������������������������������������������������������������������������������������������������ 211
Explanation�������������������������������������������������������������������������������������������������������������������������� 215

vii
Table of Contents

Project 6.1: 3D Data Visualization GUI��������������������������������������������������������������������������������������� 218


Quick Glance at the Dataset������������������������������������������������������������������������������������������������ 219
3D Data Visualization GUI Solution�������������������������������������������������������������������������������������������� 220
Explanation�������������������������������������������������������������������������������������������������������������������������� 231
Summary���������������������������������������������������������������������������������������������������������������������������������� 239

Chapter 7: Introduction to Networking with PyQt������������������������������������������������ 241


What Is Networking?����������������������������������������������������������������������������������������������������������������� 242
PyQt Networking Classes���������������������������������������������������������������������������������������������������� 242
Example 7.1: Requesting HTML from a Web Page�������������������������������������������������������������������� 243
Installing Beautiful Soup����������������������������������������������������������������������������������������������������� 244
Installing PyQtWebEngine���������������������������������������������������������������������������������������������������� 244
Explanation�������������������������������������������������������������������������������������������������������������������������� 248
Project 7.1: Email Sender GUI��������������������������������������������������������������������������������������������������� 249
What Is the Simple Mail Transfer Protocol (SMTP)?������������������������������������������������������������ 250
Setting Up Your Gmail Security Settings������������������������������������������������������������������������������ 250
Email Sender GUI Solution�������������������������������������������������������������������������������������������������������� 251
Explanation�������������������������������������������������������������������������������������������������������������������������� 256
Summary���������������������������������������������������������������������������������������������������������������������������������� 259

Chapter 8: Creating a Chatbot������������������������������������������������������������������������������ 261


What Is a Chatbot?�������������������������������������������������������������������������������������������������������������������� 262
Brief Introduction to Natural Language Processing (NLP)��������������������������������������������������� 263
The ChatterBot Library�������������������������������������������������������������������������������������������������������������� 264
Installing ChatterBot������������������������������������������������������������������������������������������������������������ 264
Creating a Simple ChatterBot���������������������������������������������������������������������������������������������� 265
Project 8.1: Chatbot GUI������������������������������������������������������������������������������������������������������������ 266
Chatbot GUI Solution����������������������������������������������������������������������������������������������������������������� 267
Explanation�������������������������������������������������������������������������������������������������������������������������� 276
Summary���������������������������������������������������������������������������������������������������������������������������������� 282

viii
Table of Contents

Chapter 9: Deploying PyQt Applications��������������������������������������������������������������� 283


Project 9.1: Audio Recorder GUI������������������������������������������������������������������������������������������������ 284
Audio Recorder GUI Solution����������������������������������������������������������������������������������������������������� 285
Explanation�������������������������������������������������������������������������������������������������������������������������� 290
Sharing Your PyQt Applications������������������������������������������������������������������������������������������������� 299
Creating an Executable with PyInstaller������������������������������������������������������������������������������ 299
What’s Next?����������������������������������������������������������������������������������������������������������������������������� 304
Summary���������������������������������������������������������������������������������������������������������������������������������� 305

Index��������������������������������������������������������������������������������������������������������������������� 307

ix
About the Author
Joshua Willman began using Python in 2015 when he
needed to build neural networks using machine learning
libraries for image classification. While building large image
datasets for his research, he needed to build a program that
would simplify the workload and labeling process, which
introduced him to PyQt. Since then, he has tried to dive into
everything that is Python.
He currently works as a Python developer, building
projects to help others learn more about coding in Python
for game development, AI, and machine learning. Recently,
he set up the site redhuli.io to explore his and others’
interests in utilizing programming for creativity.
He is also the author of Beginning PyQt: A Hands-on Approach to GUI Programming.

xi
About the Technical Reviewer
Lentin Joseph is an author, roboticist, and robotics
entrepreneur from India. He runs a robotics software
company called Qbotics Labs in Kochi, Kerala. He has 10
years of experience in the robotics domain, primarily in
Robot Operating System (ROS), OpenCV, and PCL.
He has authored several books on ROS, namely,
Learning Robotics Using Python, first and second editions;
Mastering ROS for Robotics Programming, first and second
editions; ROS Robotics Projects, first and second editions;
and Robot Operating System (ROS) for Absolute Beginners.
He has obtained his master’s in robotics and automation
from India and also worked at the Robotics Institute, CMU,
United States. He is also a TEDx speaker.

xiii
Acknowledgments
A few simple words can mean a lot to a person. They can be the little bit of hope that lets
them know everything will be okay.
I first want to thank Apress Media LLC for giving me another opportunity to write, to
learn, and to improve my creativity and skills.
To the community of Python, PyQt, and Qt programmers, thank you for your support
and assistance.
To Adrian Rosebrock at PyImageSearch, thank you for your help, words of
encouragement, and the knowledge you continue to share with others.
To Lentin Joseph, thank you for your help and support.
To Rita Fernando, thank you for your insight and help.
To Divya Modi, I am not even sure if words are enough to express how grateful I am
for your patience. I owe you my deepest debt of gratitude.
To Christine Nieuwoudt, Callum Butler, and Giulio Mazzella, thank you for being the
friends I needed so much while away from home.
To Andrea Cotman, Aaron Rountree, Vinita Acklin, and Malik Ranger, thank you for
being the friends I need who make me miss home.
To my mother, Valorie Payne, thank you for your love and support and always being
there when I need you.
To my sisters, Jazzmin and Teesha Payne, and my brother, Jason Willman, I love and
miss all of you. P.S. Teesha, thank you for your help while writing this book.
To my wife, Lijing Ye (叶丽晶), once again I have to thank you for supporting me
while I disappeared to write. I know it wasn’t easy, and I thank you for always being
supportive. <3
To my daughter, Kalani, thank you for running up to hug me when I came home in
the evening. It means the world to me.
To everyone who picks up this book, thank you for reading, programming, and
continuing to learn. Without you, this wouldn’t be possible.

xv
Introduction
When setting out to write this book, I didn’t realize that data was the underlying theme
the whole time. In everything we do now, data can be extracted. Our habits can be
analyzed and models created to improve the ways in which we live. Data can be used
to train and teach intelligent computer systems to think and make predictions. As we
continue to add to the heaps of data that already exist, our understanding of the world
continues to grow.
We understand what data is – a collection of numbers, names, words, and other types
of information. Data can either be organized or jumbled and left up to us to clean and
discern any meaning. The question this book aims to answer is how do we access and
manipulate the information hidden within. That is the beauty of PyQt and graphical user
interfaces (GUIs). We can create any application that visualizes and works with various
kinds of data, including text, images, video, audio, or anything else. With PyQt, you can
also easily leverage the power of existing Python modules in your applications.
That is what this book focuses on, showing you how to get started creating the
different tools you need to interact with the data you collect. In Modern PyQt, we will
begin to take a look at some of the ideas related to various fields and technologies that
are being used in business and research today. Topics related to business and project
management, data science, artificial intelligence (AI) and machine learning, computer
vision, and more are introduced.
PyQt is an amazing tool for creating desktop, mobile, and embedded applications.
Modern PyQt focuses on creating desktop applications for Mac, Windows, and Linux
platforms. There are so many modules and classes to cover that it is impossible to cram
them all into a single text. This guide aims to create a foundation for getting you started
in building your own GUI applications.

Who Should Read This Book


This guide is intended for intermediate-level Python programmers or above with
experience developing and coding GUIs. Modern PyQt is created both for GUI
developers who have used PyQt before and are looking for assistance in building

xvii
Introduction

applications and for programmers who have experience using other toolkits, such
as Tkinter or wxPython, and the concepts they have learned can be carried over for
developing applications with PyQt.

The Focus of This Book


It must be stressed that this book is not an introduction to UI or GUI development, PyQt,
or Python. You won’t find a section that explains how to code in Python or lists all of
the PyQt classes. There is an overview of PyQt in Chapter 1, but if this is your first time
creating GUIs, it is recommended that you don’t rely on Modern PyQt for teaching the
basics. More focus is given on the creation of applications and features that will enhance
the capabilities of GUIs.

A
 bout the Code
Each chapter contains example programs, projects, or both. Examples are designed to
introduce each chapter’s programming concepts. Projects will work toward creating
either a complete application or the foundation for a program that you can modify and
improve by adding your own features.
There are a few occasions when you will come across mathematical formulas.
Variables representing vectors and matrices are set in boldface to follow typographical
conventions.

Installing Applications in This Book


This book uses the current version of Python, version 3.8. The only exception is in
Chapter 9, when you may need to roll back to an earlier version of Python to use the
PyInstaller module.
As of this writing, the version for PyQt is version 5.15. Applications in this book will
work on Python versions 3.5 and higher.
Various chapters will require you to install different Python or PyQt packages to run
the code. There are numerous ways to install Python packages, such as installing from
source, in a virtual environment, or using package managers or tools such as Anaconda.
To keep a uniform method for installation throughout this book, the Python Package

xviii
Introduction

Installer (pip) is used. pip installs packages from the Python Package Index (PyPI).
This method will be followed unless otherwise stated in the text. If you prefer a different
method, there are tons of tutorials on the Internet to assist you.
pip should already come with Python, but if you find that you don’t have pip
installed on your computer, information about installing the package manager for your
specific platform can be found at https://pip.pypa.io/en/stable/. More information
about installing pip for Linux can also be found in the documentation.
One final thing to note is that this text installs packages using pip3 instead of pip.
With Python 2 recently no longer supported, pip3 is only used to ensure that the Python
3 environment is being used. You can still use pip instead of pip3.

How This Book Is Organized


To give the breakdown on how to get started creating desktop applications with PyQt,
Chapter 1 will walk you through many of the fundamental concepts that you will
probably need when creating an application. Not all topics are covered, only the crucial
ones for getting you started. From there, Chapter 2 will give you the lowdown on
creating applications that use the drag and drop mechanism.
Chapters 3, 4, 5, and 6 focus on working with data. Chapter 3 introduces techniques
for visualizing and analyzing 2D data using PyQt and Matplotlib. In Chapter 4, you will
get to work with PyQt’s SQL classes. Computer vision is a relatively new field that works
with visual data, including images and videos. Chapter 5 will create GUIs that integrate
the OpenCV library for computer vision applications. In Chapter 6, you’ll be introduced
to the PyQt module for working with 3D data.
From there, Chapter 7 will briefly introduce the Python and PyQt classes for
networking. Chapter 8 will explore how to create a chatbot. To wrap everything up,
Chapter 9 will demonstrate how to create executable files from your PyQt applications.

Links to the Source Code


The source code and datasets used in Modern PyQt can be found on GitHub via the
book’s product page, located at www.apress.com/9781484266021.

xix
Introduction

R
 eader Feedback
Your feedback, questions, and comments are very important. If you would like to take
a moment to let me know your thoughts about the book or ask any questions you may
have, you can send comments to the following address: redhuli.comments@gmail.com.
You can also follow me on Twitter at https://twitter.com/RedHuli.

xx
CHAPTER 1

Overview of PyQt5
Hello! Welcome to Modern PyQt! When you build an application, whether for desktop,
mobile, or embedded devices, your goal is to create a seamless experience for the user. If
you are designing a program for others to use, then you should always consider how the
user might interact with the software to solve their problems. Applications such as web
browsers, word processors, and video players are all created to enrich the end user’s life,
helping them achieve some task simply and efficiently.
Some programs are designed to perform a minimal number of tasks, such as the
clock on your computer. Others bundle together a multitude of features that allow
people to interact with machines in unique ways. An example of this is photo editing
software. What these applications generally have in common is some kind of user
interface (UI), a visual window into the happenings in human–machine interactions,
providing feedback to the user and assisting in the human’s decision-making process.
We still continue to use command-line interfaces to interact with our computers.
However, humans have naturally steered more and more to UIs that use visual controls
rather than textual prompts. These types of UIs, known as graphical user interfaces
(GUIs), utilize a computer’s graphical capabilities to create visual windows, menus,
and other elements for a user to interact with computers. Good GUI design blends
these visual components with intuitive design to improve functionality and a user’s
experience.
In Modern PyQt, we will focus on building GUI desktop applications with the Python
programming language and the PyQt toolkit. Recent years have seen an increase in the
number of both skilled and novice programmers using Python. Its uses are widespread,
being employed in general programming, web development, data science, machine
learning, game development, and more. So it’s no wonder that Python also includes
libraries for UI development.

1
© Joshua Willman 2021
J. Willman, Modern PyQt, https://doi.org/10.1007/978-1-4842-6603-8_1
Chapter 1 Overview of PyQt5

In this chapter, you will

• Find out about PyQt.

• See how to install and get started using PyQt5.

• Be introduced to some key concepts in PyQt through two practical


applications:

• Pomodoro Timer
• Basic User Manager GUI

Note This text wastes no time getting into building GUIs. Hopefully, you have
some prior experience with Python and have built user interfaces with PyQt or have
used some other UI development toolkit before, such as Tkinter or wxPython. While
the chapter is an overview of PyQt, this section only glosses over many of the
fundamental topics necessary for getting started with PyQt and building UIs. Take
a moment to review the fundamentals of PyQt if it is needed. Subsequent chapters
and topics will be handled at a much slower pace.

What Is PyQt?
With the PyQt framework, you have tools at your disposal for building UIs that can work
with SQL databases, 2D and 3D graphics, network communication, multimedia, and so
much more.
However, PyQt is in fact a set of Python bindings that make it possible to use The Qt
Company’s Qt application framework. The cross-platform C++ development toolkit, Qt,
actually contains everything you need for building applications on Windows, MacOS,
Linux, Android, and embedded systems.
This means that by combining Python with Qt, you get the advantages of the C++
toolkit for making applications, such as the collection of GUI widgets and the ease of
creating flexible UIs and reusable software elements, along with the simplicity and large
collection of modules that already exist with Python. PyQt is like the glue holding them
both together.
At the time of publication, the latest version of PyQt5 is version 5.15. PyQt4 also
exists, but as of this writing, no more releases will be made for version 4.

2
Chapter 1 Overview of PyQt5

To learn more about PyQt, which is maintained by Riverbank Computing Limited,


check out www.riverbankcomputing.com/software/pyqt/.
If you are interested in learning more about the Qt framework, then have a look at
the Qt documentation at https://doc.qt.io/.

Note PyQt contains many of Qt’s classes. However, there are some examples
when a class does not exist in the PyQt library. One notable example is the Qt QList
class. PyQt does not contain this class and rather takes full advantage of the list
data structure in Python.

I nstalling PyQt5
Before you install PyQt, take a moment to ensure that Python v3.5 or higher is already
installed on your computer. The easiest way to check your version of Python is to enter the
following command into the command line for Windows or terminal for MacOS or Linux:

$ python --version

If you find that your version needs to be updated or that you don’t have Python, the
simplest way to get the latest version is to go to https://python.org/downloads/ and
find the installer for your OS.
Like Python, there are also a few ways to download PyQt5. PyQt has both a General
Public License (GPL) and a commercial version. For this guide, we will take a look at how
to install the latest GPL version of PyQt5 with wheels and the pip package installer. Enter
the following command into your shell:

$ pip3 install PyQt5

The wheel that supports both your platform and your version of Python will be
downloaded from the Python Package Index (PyPI) repository. The PyQt5 wheel already
includes the parts of Qt that you need as well as the sip module. sip is simply a tool that
connects the Qt software written in C++ to Python.
For Linux users (specifically Ubuntu), run the following command instead to install
PyQt:

$ sudo apt install python3-pyqt5

3
Chapter 1 Overview of PyQt5

Note For more information about installing PyQt5, please refer to the “Introduction.”

To ensure that PyQt5 is properly installed, enter python3 into the command line to
open the Python interpreter. Then input

>>> import PyQt5

If there are no errors, then you are ready to start making your own UI applications.
For further information about installing PyQt5, have a look at

www.riverbankcomputing.com/static/Docs/PyQt5/installation.html.

Also, if you are ever curious to know what version of PyQt5 you have installed on
your computer, enter the following two lines into the Python shell:

>>> from PyQt5.Qt import PYQT_VERSION_STR


>>> print("PyQt version:", PYQT_VERSION_STR)

Finally, if you want to find out the path to PyQt on your system or see a list of the
PyQt5 modules you have installed, use the Python help() function:

>>> import PyQt5


>>> help(PyQt5)

After you get PyQt5 installed, you are ready to move on to this chapter’s first
application – the Pomodoro Timer.

Project 1.1: Pomodoro Timer


Given the number of distractions and challenges we all face trying to manage work,
family, and personal projects, creating a desktop application for time management as
the first project in this book seemed like the best thing to do.
The Pomodoro Technique 1 designed by Francesco Cirillo is a technique used
to increase your focus and productivity when trying to complete assignments or
meet deadlines. Choosing to use a Pomodoro Timer can help to give a task your full,
undivided attention. The timer you will be coding can be seen in Figure 1-1.

1
 ore information about the Pomodoro Technique can be found at https://francescocirillo.
M
com/pages/pomodoro-technique.
4
Chapter 1 Overview of PyQt5

A tomato-shaped kitchen timer was originally used by Cirillo. Rather than tackling an
assignment head-on for hours, this technique breaks the tasks into intervals, typically 25
minutes long (or one pomodoro). Each session of working is broken up by a short period
of rest.
The typical process of the Pomodoro Technique consists of the following six steps:

1. Choose a task that you would like to finish.

2. Set the Pomodoro Timer for 25 minutes.

3. Work solely on that task until the timer rings.

4. After the timer rings, make a checkmark on a piece of paper.

5. Take a short break. You could go outside, meditate, or do some


push-ups.

6. Once you have completed four Pomodoro cycles, you deserve


a longer break. This time could be 20, or even 30, minutes if
you need. (For this application, the long break’s timer is set to
15 minutes.) Reset your checkmarks, and then return back to
working on the task or start a new one.

Figure 1-1. The Pomodoro Timer GUI displaying the different tabs, Pomodoro,
Short Break, and Long Break. The QLCDNumber widget displays the current tab’s
remaining time. The bottom of the GUI also gives the user a field for inputting their
current task and recording the number of pomodoro cycles
5
Chapter 1 Overview of PyQt5

This project will introduce a number of the primary tools and concepts you will need
to create your own GUIs with Python and PyQt. The Pomodoro Timer GUI demonstrates
the following concepts:

• How to use PyQt modules and widget classes for creating graphical
user interfaces

• The layout management classes, including QHBoxLayout and


QVBoxLayout

• The use of container classes for organizing groups of widgets

• PyQt’s signal and slot mechanism for event handling

• How to edit the appearance of widgets with Qt Style Sheets

• The QTimer class and event loops

• Using other Qt classes such as Qt and QIcon

Note The first program in this chapter is a long one, but don’t get discouraged.
The hope is that you will continue following along and find out what this
application has to offer. By building this program yourself, you will be introduced to
some new ideas for creating your own GUIs.

In the following section, we will break apart the different widgets that comprise the
interface, discuss the layout, take a look at the code in Listing 1-1, and talk about the
logic behind the application.

Pomodoro Timer Solution


Take a moment and refer back to Figure 1-1. Underneath the title bar of the window, you
should notice three tabs labeled as Pomodoro, Short Break, and Long Break. Each tab
has its own time limit – 25 minutes for the Pomodoro tab, 5 minutes for the Short Break,
and 15 for the Long Break.
When a user clicks any one of these tabs, they will be able to use a different timer.
Each tab is distinguishable by a different color (visual attributes of widgets can be
modified using Qt Style Sheets). The user can then choose to start, stop, or reset the

6
Chapter 1 Overview of PyQt5

current timer using the QPushButtons. After the user clicks the Start button, it is disabled
until either Stop or Reset is clicked. When a user switches to a different tab, that tab’s
settings and widgets are reset.
The upper portion of the GUI that contains the tabs, timers, and buttons is separate
from the lower portion, where the user can input their current task and see how many
pomodoros they have completed. If four cycles are completed, a message will be
displayed in the task bar urging the user to take a longer break. The widgets for each
section are grouped together using container widgets and then organized using various
layout managers.
All of these points and more will be broken down in the “Explanation” section.
The design for the application created in Listing 1-1 was influenced by some of the
different Pomodoro Timers that can be found on the Internet.

Listing 1-1. Code for the Pomodoro Timer application

# pomodoro.py
# Import necessary modules
import sys
from PyQt5.QtWidgets import (QApplication, QWidget, QLCDNumber,
QPushButton, QLabel, QLineEdit, QGroupBox, QTabWidget, QVBoxLayout,
QHBoxLayout)
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtGui import QIcon
from PomodoroStyleSheet import style_sheet

# Global variables for each timer


POMODORO_TIME = 1500000 # 25 mins in milliseconds
SHORT_BREAK_TIME = 300000 # 5 mins in milliseconds
LONG_BREAK_TIME = 900000 # 15 mins in milliseconds

class PomodoroTimer(QWidget):

    def __init__(self): # Create default constructor


        super().__init__()
        self.initializeUI()

7
Chapter 1 Overview of PyQt5

    def initializeUI(self):
        """Initialize the window and display its contents to the screen."""
        self.setMinimumSize(500, 400)
        self.setWindowTitle("1.1 - Pomodoro Timer")
        self.setWindowIcon(QIcon("images/tomato.png"))

        self.pomodoro_limit = POMODORO_TIME
        self.short_break_limit = SHORT_BREAK_TIME
        self.long_break_limit = LONG_BREAK_TIME

        self.setupTabsAndWidgets()

        # Variables related to the current tabs and widgets displayed in


the GUI's window
        self.current_tab_selected = 0
        self.current_start_button = self.pomodoro_start_button
        self.current_stop_button = self.pomodoro_stop_button
        self.current_reset_button = self.pomodoro_reset_button
        self.current_time_limit = self.pomodoro_limit
        self.current_lcd = self.pomodoro_lcd

        # Variables related to user's current task


        self.task_is_set = False
        self.number_of_tasks = 0
        self.task_complete_counter = 0

        # Create timer object


        self.timer = QTimer(self)
        self.timer.timeout.connect(self.updateTimer)

        self.show()

    def setupTabsAndWidgets(self):
        """Set up the tab bar for the different pomodoro stages: pomodoro,
short break, long break."""
        # Create the tab bar and the QWidgets (containers) for each tab
        self.tab_bar = QTabWidget(self)

8
Chapter 1 Overview of PyQt5

        self.pomodoro_tab = QWidget()
        self.pomodoro_tab.setObjectName("Pomodoro")
        self.short_break_tab = QWidget()
        self.short_break_tab.setObjectName("ShortBreak")
        self.long_break_tab = QWidget()
        self.long_break_tab.setObjectName("LongBreak")

        self.tab_bar.addTab(self.pomodoro_tab, "Pomodoro")
        self.tab_bar.addTab(self.short_break_tab, "Short Break")
        self.tab_bar.addTab(self.long_break_tab, "Long Break")

        self.tab_bar.currentChanged.connect(self.tabsSwitched)

        # Call the functions that contain the widgets for each tab
        self.pomodoroTab()
        self.shortBreakTab()
        self.longBreakTab()

        # Create the line edit and button widgets and layout for Pomodoro
Taskbar
        self.enter_task_lineedit = QLineEdit()
        self.enter_task_lineedit.setClearButtonEnabled(True)
        self.enter_task_lineedit.setPlaceholderText("Enter Your Current Task")

        confirm_task_button = QPushButton(QIcon("images/plus.png"), None)


        confirm_task_button.setObjectName("ConfirmButton")
        confirm_task_button.clicked.connect(self.addTaskToTaskbar)

        task_entry_h_box = QHBoxLayout()
        task_entry_h_box.addWidget(self.enter_task_lineedit)
        task_entry_h_box.addWidget(confirm_task_button)

        self.tasks_v_box = QVBoxLayout()

        task_v_box = QVBoxLayout()
        task_v_box.addLayout(task_entry_h_box)
        task_v_box.addLayout(self.tasks_v_box)

9
Chapter 1 Overview of PyQt5

        # Container for taskbar


        task_bar_gb = QGroupBox("Tasks")
        task_bar_gb.setLayout(task_v_box)

        # Create and set layout for the main window


        main_v_box = QVBoxLayout()
        main_v_box.addWidget(self.tab_bar)
        main_v_box.addWidget(task_bar_gb)
        self.setLayout(main_v_box)

    def pomodoroTab(self):
        """Set up the Pomodoro tab, widgets and layout."""
        # Convert starting time to display on timer
        start_time = self.calculateDisplayTime(self.pomodoro_limit)

        self.pomodoro_lcd = QLCDNumber()
        self.pomodoro_lcd.setObjectName("PomodoroLCD")
        self.pomodoro_lcd.setSegmentStyle(QLCDNumber.Filled)
        self.pomodoro_lcd.display(start_time)

        self.pomodoro_start_button = QPushButton("Start")
        self.pomodoro_start_button.clicked.connect(self.startCountDown)

        self.pomodoro_stop_button = QPushButton("Stop")
        self.pomodoro_stop_button.clicked.connect(self.stopCountDown)

        self.pomodoro_reset_button = QPushButton("Reset")
        self.pomodoro_reset_button.clicked.connect(self.resetCountDown)

        button_h_box = QHBoxLayout() # Horizontal layout for buttons


        button_h_box.addWidget(self.pomodoro_start_button)
        button_h_box.addWidget(self.pomodoro_stop_button)
        button_h_box.addWidget(self.pomodoro_reset_button)

        # Create and set layout for the pomodoro tab


        v_box = QVBoxLayout()
        v_box.addWidget(self.pomodoro_lcd)
        v_box.addLayout(button_h_box)
        self.pomodoro_tab.setLayout(v_box)

10
Chapter 1 Overview of PyQt5

    def shortBreakTab(self):
        """Set up the short break tab, widgets and layout."""
        # Convert starting time to display on timer
        start_time = self.calculateDisplayTime(self.short_break_limit)

        self.short_break_lcd = QLCDNumber()
        self.short_break_lcd.setObjectName("ShortLCD")
        self.short_break_lcd.setSegmentStyle(QLCDNumber.Filled)
        self.short_break_lcd.display(start_time)

        self.short_start_button = QPushButton("Start")
        self.short_start_button.clicked.connect(self.startCountDown)

        self.short_stop_button = QPushButton("Stop")
        self.short_stop_button.clicked.connect(self.stopCountDown)

        self.short_reset_button = QPushButton("Reset")
        self.short_reset_button.clicked.connect(self.resetCountDown)

        button_h_box = QHBoxLayout() # Horizontal layout for buttons


        button_h_box.addWidget(self.short_start_button)
        button_h_box.addWidget(self.short_stop_button)
        button_h_box.addWidget(self.short_reset_button)

        # Create and set layout for the short break tab
        v_box = QVBoxLayout()
        v_box.addWidget(self.short_break_lcd)
        v_box.addLayout(button_h_box)
        self.short_break_tab.setLayout(v_box)

    def longBreakTab(self):
        """Set up the long break tab, widgets and layout."""
        # Convert starting time to display on timer
        start_time = self.calculateDisplayTime(self.long_break_limit)

        self.long_break_lcd = QLCDNumber()
        self.long_break_lcd.setObjectName("LongLCD")
        self.long_break_lcd.setSegmentStyle(QLCDNumber.Filled)
        self.long_break_lcd.display(start_time)

11
Chapter 1 Overview of PyQt5

        self.long_start_button = QPushButton("Start")
        self.long_start_button.clicked.connect(self.startCountDown)

        self.long_stop_button = QPushButton("Stop")
        self.long_stop_button.clicked.connect(self.stopCountDown)

        self.long_reset_button = QPushButton("Reset")
        self.long_reset_button.clicked.connect(self.resetCountDown)

        button_h_box = QHBoxLayout() # Horizontal layout for buttons


        button_h_box.addWidget(self.long_start_button)
        button_h_box.addWidget(self.long_stop_button)
        button_h_box.addWidget(self.long_reset_button)

        # Create and set layout for the long break tab
        v_box = QVBoxLayout()
        v_box.addWidget(self.long_break_lcd)
        v_box.addLayout(button_h_box)
        self.long_break_tab.setLayout(v_box)

    def startCountDown(self):
        """Starts the timer. If the current tab's time is 00:00, reset the
time if user pushes the start button."""
        self.current_start_button.setEnabled(False)

        # Used to reset counter_label if user has already has completed


four pomodoro cycles
        if self.task_is_set == True and self.task_complete_counter == 0:
            self.counter_label.setText("{}/4".format(self.task_complete_
counter))

        remaining_time = self.calculateDisplayTime(self.current_time_limit)
        if remaining_time == "00:00":
            self.resetCountDown()
            self.timer.start(1000)
        else:
            self.timer.start(1000)

12
Chapter 1 Overview of PyQt5

    def stopCountDown(self):
        """If the timer is already running, then stop the timer."""
        if self.timer.isActive() != False:
            self.timer.stop()
            self.current_start_button.setEnabled(True)

    def resetCountDown(self):
        """Resets the time for the current tab when the reset button is
selected."""
        self.stopCountDown() # Stop countdown if timer is running

        # Reset time for currently selected tab


        if self.current_tab_selected == 0: # Pomodoro tab
            self.pomodoro_limit = POMODORO_TIME
            self.current_time_limit = self.pomodoro_limit
            reset_time = self.calculateDisplayTime(self.current_time_limit)

        elif self.current_tab_selected == 1: # Short break tab


            self.short_break_limit = SHORT_BREAK_TIME
            self.current_time_limit = self.short_break_limit
            reset_time = self.calculateDisplayTime(self.current_time_limit)

        elif self.current_tab_selected == 2: # Long break tab


            self.long_break_limit = LONG_BREAK_TIME
            self.current_time_limit = self.long_break_limit
            reset_time = self.calculateDisplayTime(self.current_time_limit)

        self.current_lcd.display(reset_time)

    def updateTimer(self):
        """Updates the timer and the current QLCDNumber widget. Also,
update the task counter if a task is set."""
        remaining_time = self.calculateDisplayTime(self.current_time_limit)

        if remaining_time == "00:00":


            self.stopCountDown()
            self.current_lcd.display(remaining_time)

13
Another Random Scribd Document
with Unrelated Content
Midőn Pistától elvált, utolsó harczát küzdötte végig, arczát
megmelegíté a nagylelkűség, – legyőzte gőgjét, megismerte, hogy
ámbár Pista sem bátrabb, de szive nemesebb, – s ezen pillanattól
nem kivánt az emberek közt élni, hogy közönséges gyarlóságot
lásson, s e dibdáb népnek lábainál annyi legyen, mint a forgács, mit
vagy megtipornak, vagy odább löknek.
Kiment az erdőnek mélyébe, s néha födetlen fővel állt meg a
viharban, jól esett neki, mikor a szél összekóczolá, s ilyenkor
felnézett a százados tölgyre, melynek gyengébb ágait tépi meg a
vihar, maga pedig rendületlenül áll.
Télben a kályha szájánál ült, fütötte a kályhát, s az izzó parázsok
közé tekintve, agyában lerajzolá magát a harczos élet zaja, a
pattogó fának egyhangú zörejében a puskaropogás s olykor egy
hatalmas csattanásban kiegészítve lőn az ágyú, s még így
gondolatban is jól esett neki, hogy annyiszor röpült ő Pistával legelől,
s minő hátra marad el tőle a többi!
Történetünk idejében még a vad is szivesen húzódott volna el
valami sürűbe, ha az éhség ki nem veri szegény párát eledel után,
miért a rengetegeket igen gyakran messzire kellett összeszaladgálni;
mert tél és kegyetlen hideg volt, s a hótömeg ölnyire feküdt a föld
rétege fölött.
Alig törték meg az utat, már ismét behordta a szél, s a
«Kenyeretlen» csárda előtt hamarabb megállt a kocsi, mint máskor,
s a mi kis szénát összekotort nyáron a gazda, a beszorult emberek
mind elrimánkodták, hogy megkínzott barmaik valamikép éhen ne
veszszenek.
Pista volt a legutolsó vendég és látván, hogy a csárdában a
tüzelő-szalma is kifogyott, megigérte a szabadosnak, hogy másnap
estig legfölebb, megjön egy forduló szalmával, s azonkívül a
megfogyott élelmet megint kipótolja.
Néhány órával később az éjszaki szél ujabb vihart hozott, s nem
maradt embernyom az úton, csak a széles erdőnyilás vezette az
embert, ha ezen órában még az úton maradt volna, melyen a vadak
is eszeveszetten rohantak, mert vagy a vihar, vagy az éhség
kergethette őket.
A szabados hanyatlani érzé az erőt, sebeit elevenné tette a
kemény idő, melynek mérgétől nem kimélte magát, s néha órákig
elácsorgott a csárda előtt, vagy még messzebb is, ha tán valamely
megszorult utast a viharok künn szorítottak volna, – és Pista nagyon
észrevette, hogy a szabados önmagával birkózik, midőn
szenvedéseit tagadja, tehát föltette magában, hogy másnap
visszajön, nehogy inségben feledje az erdőn.
Fáradtan húzkodott be a konyhára néhány darab fát, mit előbb
vagdalt össze, – nehogy tűz nélkül maradjon, mert az utolsó szál
szalmát Pistának lovai ették meg, s míg az Keszthelyről megfordul,
ilyen zivatarban akár meg is fagyhat.
Alig veté le az utolsó fadarabot, s alig helyezkedék el egy
bundán, kegyetlen fájások rohanták meg, s majdnem elfásultan
hevert ott néhány óráig; – midőn pedig megszünvén a fájdalom, az
álom is lefogta szemét, a kályhában a parázs lassankint elhamvadt,
s mire fölébredt, már a hamu is megfázott.
Van-e valaki eleven ember ebben a házban? – szól egy ember,
kinek bajusza, szakálla jégcsappá dermedt, s mint egy csoda nézett
be a konyhaajtón.
– Itt vagyok! – mondja a szabados, fölkapaszkodván nagy kínnal,
hogy a betévedt embernek segéljen, ha tán segítségre lenne
szükség.
Az ajtó nyilásán át látta a gazda, hogy egy szánra rakott hintó áll
a félszer alatt, – előtte négy ló gőzölögve várja az enyhelyet, a
hintóból pedig két úrhölgyet segít ki egy úr és karjára fogva vezeti
őket az egykori borivóba.
– Irgalmas Isten, csakhogy megmenekülhettünk; – mondja az
idősebb hölgy, kiről a szépség virágai nem szálltak el, ámbár az
ifjabb hölgy gyermeke, de a két hölgy között alig van több különbség,
mint egy ágnak két virága közt, melyek közől az egyik a nyilott virág
egész pompájában, a másik pedig a most fakadó bimbó.
Utasaink gróf Dunay nejével és leányával, kik az egyezségre
indulának s a zivatar az útban kapta őket s ha a csárdához nem
érnek, a fáradt lovak már az úton összerogynak.
– Anyám, – édes szép anyám! – mondja a gyermeteg hölgy,
anyját átölelve, – már azt hittem, hogy az út közepén fagyunk meg
valamennyien.
A szabados megdöbbent a szóra és sietve botorkált a konyhába,
hogy a kályhában éleszsze a tüzet, de midőn kemény ujjaival a
hamuba markolt, egészen hidegnek találta.
Tűzszerszáma után kotorászott, egyetlen kénpapir darabnál
többet nem talált, de tudta azt, hogy egy szál szalma sincsen a
csárdában, mi lángot ereszszen a fa alá, hogy tüzet fogjon, aggódva
kérdé a bejövő kocsistól:
– Jó barátom, nincs széna a bakon?
– Csakhogy magunk ide értünk, hisz utóbb már a kocsiládákat is
lecsavartam és a hóba hánytam, mert a lovak alig birták el a terhet,
hanem fél zsákra való abrakom van.
– Adja a lovaknak barátom! – mondja a szabados és egy
törzsökre hanyatlott, mert megriadt a gondolattól, hogy ennyi embert
az isten hidege vegyen meg, s az istálló sokkal tágasabb volt,
minthogy azt a négy darab ló megmelegíteni birja.
Dunay kijött a szobából, hihetőleg megérezte a melegnek fogytát,
s azt mondja a gazdának:
– Van-e fája, édes jó barátom?
– Az erdőnek legmélyében vagyunk uram, hisz a fára látok ki az
ajtón.
– Szokták füteni a kályhát?
– Ma reggel még ökröt is megsüthettem volna benne, de
lenyomott a fájdalom, – beszéli a szabados, – s míg később
elszunnyadtam, az alatt elhamvadt az utolsó szikra is.
– Rakunk újra tüzet – mondja a gróf.
– Nem vártam volna a parancsolást uram; de nincs mit elgyújtani.
– Hisz akkor megfagyunk! – véli a gróf rémülten.
– Nekem jótétemény lenne uram; de szánom ott benn azt a két
ártatlan cselédet.
– Barátom!… mondja a gróf megriadva… ez igazság vagy tréfa?
– Uram, már mondám, hogy azokat sajnálom ott benn; mert hisz
mi férfiak nem ijedünk meg a haláltól, akár ma érjen el, akár holnap
– fejezi be a szabados, a kénpapir-szeletet forgatván kezében.
– Barátom, – mondja a gróf, – egy könnyű kendő meggyúl még
ettől!
– Nem hiszem, – okoskodik amaz, – alig akkora a papir, hogy a
ként rámázolhatták, – azonban próbáljuk meg, ha meg nem gyúl, –
megfagyni akkor is ráérünk.
A gróf beszaladt, de a téli ruhák között nem akadt egy darab,
mely használhatott volna, azért mielőtt a nőknek szólna, újra kiment
a konyhára, hogy finom ingét próbálja meg letépni, tán az megfogja
majd a lángot.
A szabados kiment a csárda elejére, hogyha tán elszóródott
valahol néhány szalmaszál, azonban a hó már a házoldalon kezdett
összegyülekezni, hanem midőn az erdőnyiláson végig nézne,
három-négy puskalövésnyire lát egy elakadt hintót, s valamivel idább
négy ember törtetett egyik fától a másikig.
– Nem hittem, hogy ennyien lesznek a temetésemen! – dörmögi
a szabados, ki után a gróf kisietett, s minthogy a jövőket meglátta, a
pihentebb lovakat elővezetteté, ha még megtennék a szolgálatot, és
a hóban bukdácsolókat egyenkint elhoznák.
A kocsis az első; a gróf a hátulsó lovak egyikére kapott, s az alsó
útra gázolának szél után, s ámbár elég kínnal, de mégis elég jókor
elérték a négy gyalogoló embert.
Az ösmerkedés nem sokáig tartott, – az inség előtt a lenyujtott
kéz a legnemesebb emberbarát keze, s midőn az ember halódni
készül, utolsónak vélt órájában önként nyúl leghalálosabb ellenének
keze után s a végső végórában felebarátjait látja.
Baltayt fölsegíté a gróf a lóra, s mind a négyet átengedték a
lihegő utasoknak, a gróf pedig kocsisával a törésen ballagott, s mire
a két nő akart a gróf után tekinteni, hatan nyitottak be.
Baltay és Imre, valamint András és a kocsis volt az ujon érkezett
vendég, kik bámulva néztek egymásra a szoba közepén, de itt is
András törte meg a csöndet, levetvén hóna alól egy nagy csomót,
aztán pedig a nagyságos urat kezdé kiszedni a fagyból.
– Most már itt vagyunk valamennyien, – dörmögi András, – csak
a prókátorok hiányzanak ebben a farkasordítóban, hanem találunk
majd helyettük farkasokat.
Mindenki hallgatott, egyik sem tudta folytatni a beszédet, s
minthogy sokáig tartott a hallgatás, Dunay gróf kihívta Andrást a
konyhába.
– András! – mondja a gróf, – mi itt abban a veszedelemben
vagyunk, hogy az erdőben a fa között fagyunk meg; mert nincsen
mivel alágyujtsuk a fát.
– Itt van minden gyújtószerünk, – mondja a szabados a kis
kénpapirt előmutatva, – pedig ezzel a nyers fát tudom meg nem
gyújtjuk.
– Hála légyen a jó úristenek, – mondja András, – csakhogy itt
vagyunk.
– De megkivánta kend a halódást, atyafi, – boszankodik a
szabados, – hogy így megörült kend neki.
– De még nem kivánkozom kihordozóskodni ebből a világból,
hallja, jó barátom, – mondja András, – majd csinálok én tüzet, ha
még olyan nedves is a kelmed fája.
– Az angyalok szólnak belőle, édes öregem, – véli a gróf, –
hanem ne késsék vele, fogjon rögtön hozzá, mert már a nők nagyon
érzik a hideget.
– Csak fél órát várjunk méltóságos uram, – hadd adjam meg a
módját, – azért menjen csak be, majd én az én uraimat hívom ki.
A gróf Andrásra hagyta a dolgot, – bement a nőkhöz, kik a kályha
mellett foglaltak helyet, az öreg úr pedig Imrét akarta kiküldeni, hogy
nézzen körül a házánál, hogy meg ne fagyjanak.
András kihívta a férfiakat, kik a hívásnak engedtek, s az öreg úr
Andrástól kérdezte:
– Mi a baj, András?
– Az, hogy itt fogunk megfagyni! – mondja András egész
komolysággal nézve szemközt, s elmondván, hogy nincs mit
meggyújtani.
– Ne kiáltson kend olyan hangosan! – mondja Baltay, – hisz én is
megijedtem, hát még azok a szerencsétlen asszonyok!
– No hát elhiszi a nagyságos úr, a mit mondtam? – kérdezkedék
András.
– El hát, – mondja kínosan, – csak azt sajnálom, hogy ezek a
szegény nők itt vannak.
– Magát sajnálja a nagyságos úr, jobb lesz!
– Legyen kendnek esze a pokolban, engem már elevenen
kinyújtóztathat kend!
András nem birta könyű nélkül megállni az öreg úrnak
lemondását, kivált mikor egy hosszú hallgatás után Baltay Imrére
nézett, s annak kezét részvéttel fogta meg.
– Imre, – mondja az öreg, – remélem emberré neveltelek, hanem
ha, mint remélem, tovább kibirod, mint mi, ezt a kis lányt megőrzöd,
a mig lehet.
– Bátyám, – nem tagadom, – érette szivesen meghalok.
– Szereted?
– Nem mertem eddig megmondani! – vallja be a fiú.
– Régen vártam erre, s én nem mertelek rákényszeríteni; –
mondja az öreg is megkönnyezve a végszót, s midőn kendőjeért
nyúlna, hogy könyűjét letörülje, oldalzsebében nem lelé, hanem a
helyett Kisfaludy munkáit húzta ki, mit a kilépő gróf is meglátott már.
– Nagyságos uram, – mondja András, – még van egy szál
kéngyertyánk.
– Hát aztán!
– Nem bánná meg, ha az úrfi a kisasszonyt elvenné?
– Ne támaszsza föl kend az embert, – András! – szól
reménykedve az öreg.
– Ha azt a Kisfaludyt meggyújtom ezzel a kéngyertyával, mindjárt
lesz tüzünk.
– Nem ezt akarta kend mondani, András? – véli az öreg, – tudja
kend, hogy ez legkedvesebb jószágom.
Dunay meghatottan állt az öreg háta mögött, – s láthatta, hogy
remegnek az öregnek kezei, melyekben a könyveket tartja.
– Hát nem adja oda, nagyságos uram?
– Meggyújtaná kend az imádságos könyvét? – kérdi átható
hangon Baltay.
– Nem tudom, nagyságos uram! – mondja meglepetve a hajdú.
– Nekem ez imádságos könyvem! – bizonykolja az öreg, mire
Dunay elébe lép és először annyi idő után megszólítja az öreget.
– Most meg én faragok róvást! – mondja Dunay a multakra
czélozva, mire Baltay a gróf kezét megfogván, mondja:
– Nem fogja azt tenni, – egyszersmind Andrásnak azt mondja: –
láttam, hogy elhozta kend azt a nagy pört, – gyújtsa meg kend azt, –
de Kisfaludyt el nem pörköli kend.
– Inkább a pört, mint a könyvet? – kérdi Dunay boldogságtól
csillogó arczczal.
– Megadom magamat! – vallja be az öreg, helyet adván
Andrásnak, ki a nagy csomó papirt a kályha szájához vitte, hol az
aprófa készen volt, azután egy ütet taplóval föllobbanták a
kéngyertyát, s a kis szelet papirról a láng a pörhalmaznak egyes
csomóiba kapott, s mire egy része elégett, a nedves fát is megjárta a
láng, durrogva égvén a kályhában, melyhez a didergő vendégek egy
nagy körbe ültek.
Midőn András a tűzbe lökte a pörnek utolsó levelét, azt mondja:
– Mondtam ugy-e, nagyságos uram, hogy én vetem ezt tűzbe!
– No, hogy jobban égjen, – teszi hozzá az öreg, – itt még a rovás
is, – mondja, kihúzván oldalzsebéből a rovást, mit oly régóta
hordozgat magával, – szent a béke köztünk.
Mire bemelegedett a kályha, Baltay megösmerkedett a kis
lánynyal, kit ma ölelt meg legelőször s kezét Imréébe adván, azt
mondja:
– Édes kis hugocskám, rég neked szántam én már ezt a fiút.
– Azt gondolja a nagyságos úr, – kiált közbe András, – hogy én
azt már régen nem tudtam?
– De nem tudta kend.
– Dehogy nem tudtam, – csak hogy nem akartam mondani a
nagyságos úrnak, hogy szivesen megbékülne, – csak valaki szép
módjával elkezdeni tudná.
– Semmit sem tud kend! – mondja Baltay, nagy diadallal szedvén
elő tárczájából egy rég meggyűrt levelet, s odaadá Dunaynak, ki
rögtön megismerte a boldogult herczeg írását, melynek hiányzó
sorai következők valának:
«– – – – – – – – – –
A végóra nagy későn mondja meg, édes jó barátom, hogy rövid
életünkben is temérdek jót tehettünk volna, s higyj nekem, nagy
nyugalom tudni, hogy sokan szerettek bennünket igazán, s elfeledni
akarva sem tudnak.
Öcséd, mint Dunaytól tudom, szép lelkü gyermek – Dunaynak
leánygyermeke van, ne engedd, hogy hajlékodból idegenek tanyája
legyen, a míg lehet; – vezesd össze a két gyermeket, hogy
szeretteid úgy sirassanak meg, mint az enyéim most engemet. – Ez
első és utolsó kérelme annak, ki hű barátod a sírig Herczeg
Batthyányi Lajos m. k.»
A sorokat Dunay hangosan olvasá, a két gyermek
összefogózkodék, s a nyomorult viskóban ölelkezék össze a rég
küzködő család, mely nem lelt elég helyet a széles birtokon egy
istenáldott szóra, míg a közös veszedelem egy csárda falai közt
hozta őket össze.
András három lépésről nézte őket, mint a fáradt művész nézte
ezt a munkát, mely nélküle nem tudott megkészülni, s melyből neki
csak az az osztaléka volt, a mi becsületes embernek mindenütt jut, s
miért a gazember fáradni nem akar; – az egyiknek kevés, a
másiknak pedig az öntudat végtelen jutalom.
– András! – kiált örömében Baltay, – ha haza megyünk, minden
rovást égessen kend össze.
– Senkire sem haragszik meg ezután nagyságos úr?
– Nem én, még kendre sem! – Tréfálódzék az öreg.
– Azt hiszi nagyságos uram, hogy nem lesz még olyan magyar
ember, kinek rováson a helye?
– Azt már ezután nem mi rójuk meg, hallja kend; de a
közvélemény.
XI.
(Egyezség prókátorok nélkül.)

Pista csak esteledésig maradt otthon, aztán megrakodván


élelemmel és szalmával, visszaindult, de az erdőbe nem mert
behatolni, hanem a szélső faluk egyikében meghált.
Reggelre megszünt már az orkán, de a hótömeg oly nagy volt,
hogy egyes mélyedéseken lehetetlen volt átmenni, de a becsületes
falubeliek nagy csoportban indultak meg az erdőségnek, hogy a
«Kenyeretlen» csárdást éhen veszni ne hagyják, – s ámbár a sok
mélyedés adott elég dolgot, déltájban szerencsésen megnyítottak
minden gátot, és a hű barát a csárdához ért; de nagyot csudálkozott,
midőn azt egészen megnépesedve találta.
Megösmerték egymást, mindenik örvendett a viszontlátásnak, s
midőn az első kérdezkedéseken átestek, a szabados félre hívta
Pistát.
– Pajtás! megvan még az írás, mit a kórházban átadtam?
– Megtartottam eddig.
– Barátom! – szólal meg újra a szabados, – nagyon elfáradtam
már e földön – s míg ez a bűn rajtam fekszik, nem tudok elvergődni
a más világra, – azért, ha hazatérsz, az öreg Baltaynak mutasd meg
az írást.
– Korán lesz még, Józsi!
– Láttál már engemet szaladni? – kérdé büszkén a szabados.
– Sem én, sem más! – nyugtatja meg őt a másik, megfogván
bajtársának kezét.
– Lásd, Pista, szebb úgy meghalni, ha a halálnak magam
megyek szemközt.
– Tehát mit cselekedjem?
– Add át az öregnek az írást, most már talán ő is közelebb áll
oda, hova haragos képpel belépni nem engednek senkit, mondd,
hogy bocsásson meg!
– Hisz itt van a csárdában.
– Nem bántom, – mondja a szabados, – tudom, régen örült
ennyit; minek rikassam meg?
– A mint te akarod, pajtás, – nyugtatja meg amaz, – tehát
hazamenet.
Pista kocsiját a fiatalabb urak foglalák el és az öreg András, a
másikon pedig a nők és Baltay foglalának helyet, hogy estére még
Keszthelyre érjenek.
Az elválás előtt beszólíták a szabadost s a gróf kérdi tőle:
– Édes jó barátom, adósok nem akarunk maradni! – mondja, egy
erszényt húzva ki, melyben aranyok valának, – de a szabados
hunyászkodás vagy kevélység nélkül mondja:
– Méltóságos uram, én sem fizetek senkinek, nekem sem fizet
senki.
– De tőlünk mégis elveszen valamit.
– Semmit sem, méltóságos uram! Mi haszonra is adná, elkölteni
úgy sem tudnám, maradékom nincsen, veszendőnek pedig kár volna
itt hagyni.
– Barátom, – unszolá a grófné, – gyermekem boldogságát e
helyen értem meg.
– Adós voltam vele; – mondja hirtelen a szabados, látván, hogy
az öreg Baltay kiment, – mit Pista is észrevett, s a grófnak sietve
mondja.
– Hiába kinál ennek valamit, – méltóságos uram, – ez már ilyen
ember.
A gróf sajátszerűnek, de egyszersmind megmagyarázhatlannak
találván a dolgot, – nem unszolá tovább, hanem kezet szoríta vele,
mire aztán azt mondja a szabados:
– Egy kérésem volna méltóságos uram, ha szószólómmá lenne.
– Édes örömest – felel rögtön a gróf, – hadd hallom, mit kiván?
– A méltóságos asszonyságok kezeit szeretném megcsókolni, ha
tán megengednék.
A két hölgy örömmel nyújtá oda a kezét, s midőn mindkettőt
megcsókolá, a grófné érzé, hogy egy könycsepp csordult ki a rideg
ember szemeiből, mit a grófné nem tudott megérteni, azért
megilletődve kérdi:
– Barátom, könnyezik?
– Jól esik ez nekem, méltóságos asszonyom; mert akkor sem
tudtam sirni, mikor apámat temették.
Minden oly megfoghatatlan, hogy a család maradni szeretne, –
de bejött az öreg, s unszolja őket a menésre, minek az a sikere lőn,
hogy egy bucsúköszöntés után a nők és a gróf kimenének. Baltay
pedig azt mondja a szabadosnak:
– Nem feledkeztem el, becsületes ember; – hanem addig is isten
velünk, hadd szorítom meg a kezét.
– Nem lehet, nagyságos uram, nem érdemlettem meg.
– A patvarba, – kinek szoríthatnám meg a kezét szivesebben,
mint a kendét?
– Nagyságos uram, – várjuk meg a holnapi napot.
– De én most menni akarok s holnapig nem várok.
– Nem tartóztatom a nagyságos urat, – huzakodék a szabados, –
hanem holnap ilyenkor gondoljon rám, és ha akkor azt gondolja, a
mit most, nékem annyi, mintha kezet szorítana velem.
– Holnap is csak azt gondolom, a mit ma!
– Megtudom én azt is, – hanem éppen azért várjuk el a holnapi
napot.
– Na, legyen! – mondja Baltay; – agyafurt ember kend, – hanem
azért derék ember, ezt én mondom, Baltay.
– Bárcsak holnap is azt mondaná, nagyságos uram.
– Jó éjszakát! – búcsúzik Baltay; – tehát holnap ilyenkor
egymásra gondolunk.
– Azért jót állok, hogy nem feledjük el egymást, – végzi be a szót
a szabados, aztán pedig kiállt a csárda elejére s a távozó kocsik
után nézett mindaddig, míg az erdőnyilásból ki nem tértek, aztán
pedig a kályha szája elé ült le, folytatta a munkát: nézte a kályhában
a tüzet s mintha összeszámolt volna a világgal, könnyebbült kebellel
piszkálta az izzó szenet, s újra lerajzolódának emlékében az egykori
csaták, melyeket látni alig lesz már többé alkalma: de a régiekből
valamit feledni nem tud és nem akar.
Tán én is találtam volna egy bitófát, hová ezt az embert
kiköthetném s hű maradtam volna a nagy világ büntető törvényéhez,
mely addig nem talál megnyugvást, míg a bűnöst agyon nem veri.
Oh, mily érdekes olvasmány, látni egy embert, kinek lelkét az író
végighúzkodja a sáron, aztán pedig kilöki a szemétre, hogy még
több undokság ragadjon rá s mikor már egészen bizonyos, hogy
minden jó gyomrú ember megundorodik tőle, a szellemdús író
készen van elmondani azt, mi a varjúknak dobatik, – hisz mi köze
hozzá az írónak, hogy a tolvajt fel szokták kötni, – ő megtette a
magáét, földhöz verte a lelket, a testet miért kimélnék? – a közönség
érdekes olvasmányt akar, – ime, nyársba van már húzva egy ember,
tisztelt olvasó közönség, tessék ordítani!
A húsz esztendős gyermek egy bolond órájában elvét egy lépést,
nincsen ember, ki utána nyúljon, hogy negyven-ötven esztendőnek
megmentse. Minek is! megbotlott vagy szántszándékkal esett el,
mindegy: kötözd meg. Ha ló lenne, s a lovat megcsipné egy légy és
kínjában kirugván, a kocsist is eléri, összeszamarazzák a kocsist, s
a ló – abrakot kap megint. – A pénzdarab leesik, felveszik a porból,
lefujják róla a port, zsebre teszik megint, – senki sem emlegeti
többé, hogy elesett; – csak az embert lökik vissza a sárba; – egygyel
több vagy kevesebb – az mindegy!
Utálom e lelketlen eljárást, s ha már a többség ilyen bolond,
tegyünk kivételt is, bizony-bizony ráértünk már egyszer.
Mire beesteledett volna végképen, Keszthelyre értek a vendégek.
Festetics a kocsizörejre lesietett s a nagy lépcsőhöz érve bámult
el, midőn a haragos atyafiakat együtt jönni látta, – azonban nem
sokáig késtek a megmagyarázással, s általános öröm lőn a
keszthelyi kastélyban.
Másnap reggel együtt reggelizett a család. András az
előteremben beszélgetett Pistával, kit a gróf felkéretett, mert hitte,
hogy a «Kenyeretlen» csárdának lakójáról többet tud mondani, –
különösen pedig azt akarta tudni, miért volna adósa nejének még
boldogságával is?
A reggelizés után Baltay kezét a grófnak nyujtván, átment saját
szobájába, hová András Pistát vezette be.
– Mi jót hozott, édes barátom? – kérdi nagy szivességgel az
öreg.
– Ezt a kis papirdarabot hoztam el, nagyságos uram, – mondja
Pista, – most már nincs mit titkolódznom, tessék elolvasni.
Baltay elhalaványult, valamint a gróf is, és az öreg remegő kézzel
nyult a papiros után, mely jól megöregedett, mióta Pista tartogatta;
hanem azért a belseje tisztán olvasható s az öreg úr elolvasta a
vallomást.
– Ki írta alá mint tanú? – kérdi az öreg.
– Én és a kórházi felügyelő, – felel Pista, – hisz ott van az én
nevem mellett a főorvosé, tisztán ki van írva.
– Semmi kétség! – mondja az öreg, – a főorvos kezeírását
ösmerem, ő általa tudtam meg, hogy a pör a körmendi levéltárban
van letéve.
– A másik tanú pedig én vagyok.
– S a ki megölte?
– Ott a neve, nagyságos uraim, – a boldogtalan nekem szánta a
golyót és az úrfit találta el!
– Bocsásson meg neki a jó isten, én nem átkozhatom el.
– Nagyságos uram! – mondja Pista, – én még más szót is várok.
– Mit mondjak még, édes jó barátom?
– Hogy nemcsak nem átkozza el, de meg is bocsát neki.
– Tehát megbocsátok neki!
– Tüstént megyek, nagyságos uram, megviszem neki ezt a
vigasztalást.
– És még élne ez az ember?
– Tegnap valamennyien vendégei voltunk a csárdában,
nagyságos uram!
– Az a sánta ember?
– Kit úgy vert meg a sors, hogy az enyém helyett az ő lábát vágta
el az orvos, – mondja Pista, egyszersmind elbeszélvén az egész
dolgot, mint a hogy az Pécsett megtörtént velük.
– Úgy ez az az ember, kivel a hadjáratban az erdőnyilásban
álltak? kérdi a gróf.
– Ott kaptuk a sebeket s az ágyúzás után kerültünk kórházba.
– Nem avatkozom az isten dolgába, – mondja az öreg, – látom,
büntető keze hamarabb elérte, mint én tudtam volna; ha az ég
megelégelé e szenvedést, én meg is sokallom és megbocsátok neki.
– Isten velünk! – mondja Pista s egy negyed mulva már megint
az erdő felé tartott. Baltay nem birt megválni a gondolattól, mely
néhány óráig nyomta, de midőn újra visszaélte a multat s elért a
jelenig, mely boldogságot kinált öreg napjainak, lassankint
lemaradozott a bánat s a két fiatalnak boldogsága félretolta az utolsó
ködöt is.
Alkonyatkor utólszor emlékezék a dologról s midőn elérte azt a
pontot, mely a tegnapi órának ideje volt, a mogorva szabados arczát
maga előtt látta, – megérté, hogy e vad vonásokon az erő duzzadt ki
egykoron s bár nagyot hibázott egyszer a kéz, elszenvedte azt
százszor és megrettenés nélkül vádolja el magát.
– Derék ember! – mondja hangosan az öreg, bemenvén
kedvenczeihez, kik a háborítatlan látás boldog örömeit érzék, – míg
a szabados étlen-szomjan várta Pistát a csárda előtt, mert megigérte
Pista, hogy hírmondónak bármi későn megjön.
Az időnek rideg képe lassankint elhomályosodott, hanem még
tisztán látta az úton a fekete pontot, mely fához mérve mindinkább
közeleg s néhány óranegyed mulva megérkezett a nagy kínnal várt
vendég.
– Megbocsátott! – mondja Pista a szabadosnak, ki egy szót nem
tudott felelni, hanem állva maradt egy helyben, míg Pista gőzölgő
lovait a nyughelyre vezette s a nagy istállóban tüzet rakott, hogy
szegény párákat meg ne ölje majd a hideg.
Magunk is érezzük, hogy e pillanatban lehető legkevesebbet kell
mondanunk s magunk is habozunk, nem tudván megosztani e
fejezetet, melybe két különvált képet kell illesztenünk, – az egyik a
mogorva szabados, kit a bocsánat fogott le, a másik a boldog
család, melyből most már az öreg anya sem hiányzik, hanem
szerettei között ül, nem gondolván a multnak szenvedéseire, ajkára
nem fért egyetlen szemrehányás, hanem áhítatos buzgalommal
bámulta a gondviselés művét, mely a szétszakadt szálakat ily nem
várt módon illesztette össze.
Alakjainkkal nem fogunk többé találkozni, sorsuk most már nem
érdekel bennünket, – küzdelmük közben megérett az az eszme,
melyért tollat fogánk: az irodalom nem árva többé, hanem egy
harczos, mely eszméivel hódít.
Baltay hű maradt Kisfaludyjához; András megelégedett
önmagával, hisz ő azon emberek közé tartozott, kik nem várnak
dicséretet, – mert az igazságot gorombán is megmondja, ha máskép
meg nem hallgatják, – s midőn egyedül maradt, egyet ránt dolmánya
szárán, mi nála körülbelül annyit tesz, mintha valami nálánál is
külömb ember megveregetné a vállát.
Festetics végighallgatván a történetet, midőn Baltayval megint
végignézék a keszthelyi intézetet, elégülten mondja:
– Barátom! – a mi szerepünk eddig tart; a többi a fiatalok dolga.
*
Midőn a Bakony erdején oly sűrű lőn a falevél, hogy a
madárfészek elrejtőzködhetett, Pista megint az erdő felé megyen; de
lovait most már nem ereszté meg oly sebesen, mint máskor, hisz
nincsen, ki vendégképen várja, meghalt a kifáradt ember s ma már a
nyughely várakozik reá.
Pista néhány csonka vitézt rakott föl kocsira s ezekkel adta meg
a legutolsó tiszteletet, a hidegült tetemet visszaadván a földnek.
A csárdától nem messze, a forráshoz is közel kikereste a
legárnyékosabb helyet s elkészíté az öröktanyát, míg az ébredésnek
órája el nem jön.
Nem volt ének, nem volt búcsúztató; nem volt osztozkodó nép,
hogy a temetésről visszajövén, elosztozzék a maradékon és még
össze is marakodjanak az aprólékon, hol a gombostűt is
megválogatják, nehogy egygyel többet vagy jobbat hordjon el a
másik.
A legszebb hantokat válogatták s nyirfának ágából illesztettek
össze egy keresztet s a mező virágaiból még koszorú is került.
Ledült a fa, árnyéka sincs többé, elrothadt porát fogja majd csak
egykor széthordani a szél, messze, mindenfelé; ki szedi megint azt
össze?
A hitetlennek nagyobb kínja nem lehet végórájában, mint hogy a
léleknek halhatatlanságát nem meri elhinni, pedig de szívesen
elhinné!
Higyjetek és üdvözülni fogtok!
XII.
(Fele enyém, fele meg tied.)

Olvasóm lámpája elalvófélben van, tán nem is látja meg a vékony


fonalat, melynek vége mindjárt kezembe jő, pedig még egy csomót
kell eloldanom, s még egyszer meghurczolom azt a türelmet, mely e
fonaleregetést három köteten keresztül végigvárni tudta.
Még egyszer keressük föl az egykori bérest, kitől láttatlanban
magam sem tudnék elbúcsúzni, ki tán mai napig is csak olyan erős,
mint az ozorai búcsún, csakhogy a ki izengetne neki, a föld alatt
nyugszik már.
Sümeg felől jön a grófi fogat, a négy táltos tajtékot ver az úton, s
Holvagy Pistának lakása előtt száll ki a kocsiból Kisfaludy Sándor, s
a gazdát az udvaron találja.
– Megint látjuk egymást! – mondja Kisfaludy, megszorítván a
megkeresett jobbot.
– Hála legyen érte a felséges úristennek, – válaszol rá Pista.
– Gondolja-e, miért jöttem ily sebes vágtatást?
– Ellenséget nem láttam erre jönni, – véli Pista, – különben azt
hinném, hogy vitéz őrnagy uram talán ellenséget hajtott.
– Budáról jövök, még pedig egyenesen a nádor ő fönségétől.
– Bizony odáig is hosszú az út, hát még onnét vissza! – üres
kocsinak is elég.
– Én pedig nem jöttem üresen! mondja Kisfaludy.
– Okos embernek a fejében is elég hordani valója van.
– Emlékszik-e barátom azon napra, midőn az erdőszélen
legelőször láttuk egymást?
– Egy kicsit emlékszem még az ágyúszóról, – mondja a másik, –
egy pár ágyút elsütöttek ránk emlékezet okáért.
– No hát, hogy még bizonyosabban megemlékezzék, kedves jó
barátom, – mondja Kisfaludy, oldalzsebébe nyúlva, – ime ez arany
érdempénz, ezt a nádor küldi.
Kisfaludy a bámuló embernek mellére tűzte az érdempénzt, s az
egyszerű embert oly remegés fogta el, mintha éppen most állítanák
szemközt azon ágyúkkal, melyeket egykor az erdőszélen rájok
sütögettek, s mintha a mellére azért tennének olyan fényes
aranykarikát, hogy az ágyúsütögetők odalőhessenek.
Míg Kisfaludy a feltűzéssel vesződött, a ház népe összeszaladt,
előbb a kapu mellől bámulták a dolgot, később megközelíték őket,
utóbb a férfiak levett kalappal álltak meg, utoljára pedig egyik sem
tudta megállni a sirást, hanem megeresztette a könyűt, mely
törületlenül folydogált le, s midőn még közelebb mertek jőni, Pista
kinyujtá kezét, melyet sorban szorongattak, és ránéztek a tündöklő
pénzre, melyért az ágyúk közé kell napszámba menni, s mit nem
szokás apróbbra váltani, mert ilyen mellett éhen is szivesen
meghalhat az ember.
Tudta az egyszerű nép, hogy azt a csillogó aranyat azért tették a
mellére, hogy az nem a költőpénz közé való s milyen szépen odaillik
a széles mellre, legalább mikor a gazda nagy ünnepen második
harangszóra szentegyházba indul, jobbról-balról kitér a sok ember,
és még a szentegyházban is a legelső padig eresztik, hogy minden
ember lássa példának okáért!
Mire föltűzte Kisfaludy az érdempénzt, a hátulsók közül kiszalad
egy surjány legény az utczára s minden arra menőt becsődített,
hogy a nagy becsületnek több nézője legyen. Pista pedig még
mindig egy helyben állt, mint a gyermek, kit husvétnapra öltöztet az
anyja.
Welcome to our website – the ideal destination for book lovers and
knowledge seekers. With a mission to inspire endlessly, we offer a
vast collection of books, ranging from classic literary works to
specialized publications, self-development books, and children's
literature. Each book is a new journey of discovery, expanding
knowledge and enriching the soul of the reade

Our website is not just a platform for buying books, but a bridge
connecting readers to the timeless values of culture and wisdom. With
an elegant, user-friendly interface and an intelligent search system,
we are committed to providing a quick and convenient shopping
experience. Additionally, our special promotions and home delivery
services ensure that you save time and fully enjoy the joy of reading.

Let us accompany you on the journey of exploring knowledge and


personal growth!

textbookfull.com

You might also like