본문 바로가기
Qt5 Python GUI Programming Cookbook

Working with Date and Time

by 자동매매 2023. 2. 28.

In this chapter, we will cover the following topics:

  • Displaying LCD digits
  • Displaying system clock time in LCD-like digits
  • Displaying the data selected by the user from Calendar Widget
  • Creating a hotel reservation form
  • Displaying tabular data using Table Widget

 

Displaying LCD digits

Qt Designer enables us to display LCD-like digits of any size by making use of its LCD Number widget. The LCD Number widget is an instance of the QLCDNumber class and it can be used to display decimal, hexadecimal, octal, and binary digits of any size. The methods provided by QLCDNumber are as follows:

  • setMode(): This method is used to change the base of the numbers. Available options are as follows:
  • Hex: This option is used to display hexadecimal digits
  • Dec: This option is used to display decimal digits
  • Oct: This option is used to display octal digits
  • Bin: This option is used to display binary digits
  • display(): This method is used to display the supplied data in LCD digit format.
  • value(): This method returns the numerical value displayed by the LCD Number widget.

We want the displayed system clock time to be updated automatically. For this, we need to implement timers.

 

Using Timers

Timers are used for performing repetitive tasks. A timer is an instance of the QTimer class. The task to be repeated needs to be written in a method and that method, in turn, is invoked via the timeout() signal of the QTimer instance. The timeout() signal can be configured or adjusted using the following methods:

  • start(n): It compels the timer to generate the timeout() signal at n millisecond intervals
  • setSingleShot(true): It constrains the timer to generate the timeout() signal only once
  • singleShot(n): It makes the timer generate a timeout() signal only once, and that too after n milliseconds

Before we go ahead and make an application, we need to understand one more class, QTime, which is used to fetch and measure system clock time.

 

Using the QTime class

The QTime class not only helps in reading the current time from the system clock but also provides all clock time functions. It shows time in terms of hours, minutes, seconds, and milliseconds since midnight. Also, it helps in measuring the span of elapsed time. The time returned by the QTime class is in 24-hour format. The methods provided by the QTime class are as follows:

  • currentTime(): This method accesses the system clock time and returns it as a QTime object
  • hour(): This method returns the number of hours
  • minute(): This method returns the number of minutes
  • seconds(): This method returns the number of seconds
  • msec(): This method returns the number of milliseconds
  • addSecs(): This method returns the time after adding the specified number of seconds
  • addMSecs(): This method returns the time after adding the specified number of milliseconds
  • secsTo(): This method returns the difference in the number of seconds between two QTime objects
  • msecsTo(): This method returns the difference in the number of milliseconds between two times

Displaying system clock time in LCD-like digits

Liquid Crystal Display (LCD) digits are a seven-segment display that is commonly used in almost all electronic devices. These LCD digits are much more readable than dot matrix displays. Let's create an application that displays system clock time in LCD-like digits.

 

demoLCD.py
0.00MB
demoLCD.ui
0.00MB

 

 

 

How to do it...

In this application, we will be making use of the QTime class to fetch the current system's time. Following are the steps to create such an application:

  1. Open Qt Designer and create a new application based on the Dialog without Buttons template.
  2. Save the application with the name demoLCD.ui.
  3. Since we want to display LCD-like digits, drag and drop the LCD Number widget onto the form, as shown in the following screenshot:
  4. From the Property Editor window, set the Width and Height properties of the LCD Number widget to 100 and 40 respectively, just to make the system clock quite visible. Use the pyuic5 command utility to convert the .ui (XML) file into Python code. The generated Python demoLCD.py file can be seen in the source code bundle of the book.
  5. Create a Python script named callLCD.pyw which imports the code, demoLCD.py, to invoke the user interface design and display the current system clock time through the LCD Number widget.
  6. The script must also include a timer to keep updating the LCD display at fixed intervals. The Python callLCD.pyw script appears as shown here:

import sys

from PyQt5.QtWidgets import QDialog, QApplication

from demoLCD import *

class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        timer = QtCore.QTimer(self)
        timer.timeout.connect(self.showlcd)
        timer.start(1000)
        self.showlcd()
  
    def showlcd(self):
        time = QtCore.QTime.currentTime()
        text = time.toString('hh:mm')
        self.ui.lcdNumber.display(text)
 
if __name__=="__main__":    
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

 

How it works...

In this code, you can see that an instance of QTimer is created with the named timer, and its timeout() signal is connected to showlcd(). Whenever timeout() is generated, the

showlcd() method will be invoked. Also, via start(), you set the timer to generate a timeout() signal after every 1,000 milliseconds.

In the showlcd() method, you fetch the current system clock time, convert it into a string data type, make it appear in the HH:MM format, and display it with the LCD Number widget, as shown in the following screenshot:

 

Displaying the date selected by the user from Calendar Widget

This application will make use of two widgets, Calendar Widget and Date Edit. The date selected by the user from Calendar Widget will be reflected in the Date Edit widget. Both widgets are commonly used when displaying current date as well as the date required by the user, with the only difference that Calendar Widget has a bigger and more readable visual, whereas the Date Edit widget consumes much less space.

 

Getting ready

To make this recipe, we need to understand the following things first:

  • Calendar Widget displays the desired monthly calendar
  • The QDate class accesses the date from the system clock
  • The Date Edit widget will display the date that is selected from Calendar Widget

So, let's first understand the preceding widgets and class one by one.

 

Displaying a calendar

In order to enable the user to select a date, you need to display a monthly calendar. Calendar Widget in Qt Designer helps in doing so. This widget is an instance of the QCalendarWidget class that displays the current month and year by default and can be changed if desired. The days appear in short form (Sun, Mon, Tue, and so on), and Saturday and Sunday are marked in red. Also, Sunday is displayed as the first column in the calendar. You can use the following properties of Calendar Widget to configure its display:

  • minimumDate: This property is used for specifying the minimum date range.
  • maximumDate: This property is used for specifying the maximum date range.
  • selectionMode: This property helps in enabling or disabling the user's ability to select a date from Calendar Widget. If this property is set to NoSelection, it will not allow the user to select any date.
  • verticalHeaderFormat: You can remove the week numbers from Calendar Widget by setting this property to NoVerticalHeader.
  • gridVisible: This property helps in making the calendar grid visible or invisible. You can set this property to the Boolean value True to make the calendar grid visible.
  • HorizontalHeaderFormat: This property is used for setting the days format to be displayed. The following are the available options:
    • SingleLetterDayNames: A single letter for days is displayed in the header, such as M for Monday, T for Tuesday, and so on.
    • ShortDayNames: The short form of days are displayed in the header, such as Mon for Monday, Tue for Tuesday, and so on.
    • LongDayNames: The header displays days in complete forms, such as Monday, Tuesday, and so on. NoHorizontalHeader: Using this option in HorizontalHeaderFormat makes the header invisible.

The methods provided by QCalendarWidget are given in the following list:

  • selectedDate(): This method returns the currently selected date. The date is returned as a QDate object.
  • monthShown(): This method returns the currently displayed month.
  • yearShown(): This method returns the currently displayed year.
  • setFirstDayOfWeek(): This method is used to set the day of the week in the first column.
  • selectionChanged(): This method is invoked when the user changes the currently selected date.

Let's look at the QDate class as the system date is returned as an instance of this class only. Also, the QDate class provides methods to extract the year, month, and day from the QDate instance.

 

Using the QDate class

The QDate class helps in handling dates. The instance of the QDate class accesses the date from the system clock and displays the date, which includes the year, month, and day, using the Gregorian calendar. The following is the list of methods provided by the QDate class:

  • currentDate(): This method returns the system date as a QDate instance.
  • setDate(): This method sets the date based on the supplied year, month, and day.
  • year(): This method returns the year from the specified QDate instance.
  • month(): This method returns the month from the specified QDate instance.
  • day(): This method returns the day from the specified QDate instance.
  • dayOfWeek(): This method returns the day of the week from the specified QDate instance.
  • addDays(): This method adds the specified number of days to the specified date and returns the new date.
  • addMonths(): This method adds the specified number of months to the specified date and returns the new date.
  • addYears(): This method adds the specified number of years to the specified date and returns the new date.
  • daysTo(): This method returns the number of days between two dates. daysInMonth(): This method returns the number of days in the specified month.
  • daysInYear(): This method returns the number of days in the specified year.
  • isLeapYear(): This method returns true if the specified date is in a leap year.
  • toPyDate(): This method returns the date as a string. The format parameter determines the format of the result string.

The following expressions are used for specifying the format:

  • d: This expression displays the day as a number without a leading zero (1 to 31)
  • dd: This expression displays the day as a number with a leading zero (01 to 31)
  • ddd: This expression displays the day in short format (Mon, Tue, and so on)
  • dddd: This expression displays the day in long format (Monday, Tuesday, and so on)
  • M: This expression displays the month as a number without a leading zero (1 to 12)
  • MM: This expression displays the month as a number with a leading zero (01 to 12)
  • MMM: This expression displays the month in short format (Jan, Feb, and so on)
  • MMMM: This expression displays the month in long format (January, February, and so on)
  • yy: This expression displays the year as a two-digit number (00 to 99)
  • yyyy: This expression displays the year as a four-digit number

Let's take a look at the following examples:

  • dd.MM.yyyy will display the date as 15.01.2018
  • ddd MMMM d yy will display the date as Sun January 15 18

To display the date that is selected by the user in Calendar Widget, you use a Date Edit widget.

Using the Date Edit widget

To display and edit dates, the Date Edit widget is used, which is an instance of the QDateEdit class.

The properties used to configure the Date Edit widget are as follows:

  • minimumDate: A minimum date can be defined for the widget by making use of this property
  • maximumDate: A maximum date can be defined for the widget by making use of this property

The following are the methods provided by the QDateEdit class:

  • setDate(): This method is used to set the date to be displayed in the widget
  • setDisplayFormat(): This method is used to set the date format for the date being displayed in the Date Edit widget

The formats, with their output, are as follows:

  • dd.MM.yyyy 15.01.2018
  • MMM d yy Jan 15 18
  • MMM d yyyy Jan 15 2018
  • MMMM d yy January 15 18

As mentioned previously, in the following application you will learn to display the date that is selected by the user in Calendar Widget with the Date Edit widget.

demoCalendar.py
0.00MB
demoCalendar.ui
0.00MB

 

 

 

How to do it...

Both widgets, Calendar Widget and Date Edit, are meant for accepting dates, with the only difference that Calendar Widget has a bigger display and shows weekdays too, along with the dates, whereas the Date Edit widget provides the spin buttons to spin between days, months, and years. Here are the steps to build an application that displays the date selected through Calendar Widget in the Date Edit widget:

  1. Open Qt Designer and create a new Dialog without Buttons template.
  2. Drag and drop the Calendar Widget and Date Edit widgets onto the form,
  3. Save the application with the name demoCalendar.ui. The application is shown in the following screenshot:

The pyuic5 command utility will convert the .ui (XML) file into Python code. You can find the generated Python script, demoCalendar.py, in the source code bundle of the book.

Create a Python script named callCalendar.pyw that imports the code, demoCalendar.py, to invoke the user interface design and display the selected date from Calendar Widget in the Date Edit widget. The Python script, callCalendar.pyw, appears as shown here:

import sys

from PyQt5.QtWidgets import QDialog, QApplication

from demoCalendar import *

class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.ui.calendarWidget.selectionChanged.connect(self.dispdate)
        self.show()

    def dispdate(self):
        self.ui.dateEdit.setDisplayFormat('MMM d yyyy')
        self.ui.dateEdit.setDate(self.ui.calendarWidget.selectedDate())


if __name__=="__main__":    
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

 

How it works...

In the code, you can see that the selectionChanged signal of Calendar Widget is connected to the dispdate function. Hence, as the user selects a date, the

dispdate function will be invoked. In the dispdate function, the date selected by the user is retrieved through the selectedDate() method and displayed in the Date Edit widget through setDate.

On running the application, Calendar Widget will display the current system date and the Date Edit widget will simply display the default date, 01/01/2000.

The date is displayed in the default date format, mm/dd/yyyy, as shown in the following screenshot:

On selecting any date from Calendar Widget, the selected date will be displayed on the Date Edit widget, as shown in the following screenshot:

You can display the date in a different format with the setDisplayFormat() method. Let's modify the dispdate() function to display the date in MMM d yyyy format:

def dispdate(self):
self.ui.dateEdit.setDisplayFormat('MMM d yyyy')
self.ui.dateEdit.setDate(self.ui.calendarWidget.selectedDate())

Now, the date selected from Calendar Widget will appear in the desired format in the Date Edit widget, as shown in the following screenshot:

 

Creating a hotel reservation form

This application will display Calendar Widget, prompting the user to select the date for reserving a room. Also, a Spin Box widget will be displayed that asks the user to choose the number of days they want to stay. Besides this, a Combo Box widget will be displayed on the hotel reservation form that prompts the user to select the room type. The room rent will be based on the selected room type.

 

 

Getting ready

Before we begin creating a hotel reservation form, let's understand the use of the Combo Box widget first.

In order to display several options in minimum space, Combo Box is preferred. The QComboBox class is used for displaying a Combo Box widget. Not only text, but graphic images too can be displayed via a Combo Box widget. Here are the methods provided by the QComboBox class:

  • setItemText(): This method is used to change the item in the Combo Box widget.
  • removeItem(): This method is used to remove an item from the Combo Box widget.
  • clear(): This method is used for removing all items from the Combo Box widget.
  • currentText(): This method returns the text of the currently selected item from the Combo Box widget.
  • setCurrentIndex(): This method is used to set the current item.
  • count(): This method returns the count of the number of items in the Combo Box widget.
  • setMaxCount(): This method is used to set the maximum count of the number of items allowed in the Combo Box widget. It sets the maximum capacity of the Combo Box widget.
  • setEditable(): If the Boolean value True is passed to this method, it will make the Combo Box widget editable.
  • addItem(): This method is used to append the specified text to the Combo Box widget.
  • addItems(): This method is used to append each of the strings supplied in this method to the Combo Box widget. Each string is appended, one below the other.
  • itemText(): This method returns the text at the specified index location in the Combo Box widget.
  • currentIndex(): This method returns the index of the currently selected item in the Combo Box widget. An empty combo box or a combo box with no selected item returns -1.

The signals generated by the Combo Box widget are shown in the following list:

  • currentIndexChanged(): This signal is emitted if the index of the Combo Box widget is changed, that is, when some text other than the currently selected text is chosen in the Combo Box widget
  • activated(): This signal is emitted when the index is changed by user interaction
  • highlighted(): This signal is emitted when the user highlights an item in the Combo Box widget
  • editTextChanged(): This signal is emitted when the text of an editable Combo Box widget is changed

The next application is a hotel reservation form that prompts the user to specify the date of the reservation, the number of days staying, and the room type the user wants to book. Then, it computes the total room rent accordingly. The user can specify the date of his journey with Calendar Widget, the number of days with a Spin Box widget, and the room type with a Combo Box widget. The Combo Box widget will display four room class options: Suite, Super Luxury, Super Deluxe, and Ordinary room. The rate of these room types is assumed to be $40, $30, $20, and $10, respectively.

 

reservehotel.py
0.00MB
reservehotel.ui
0.00MB

 

 

 

How to do it...

In this application, you will learn to make use of Calendar Widget, Spin Box, and Combo Box. All three widgets make the data entry easier and error-proof. The Calendar Widget item gives you the comfort of switching to the desired month and day. Similarly, the Spin Box widget enables you to select a value from the available options; the user cannot enter any invalid data and this is also the case with the Combo Box widget. This is the step-by- step procedure to develop this application:

  1. In the application, six Label widgets, a Calendar Widget item, a Spin Box widget, a Combo Box widget, and a Push Button widget are used.
  2. The text property of the first four Label widgets is set to Hotel Room Reservation, Date of Reservation, Number of days, and Room type.
  3. Set the objectName property of the fifth and sixth Label widgets to Enteredinfo and RoomRentinfo, respectively.
  4. The Enteredinfo widget will be used to display the options selected in the different widgets by the user, and the RoomRentinfo widget will be used to display the computed room rent.
  5. Delete the text property of the two Label widgets, Enteredinfo and RoomRentinfo, to make them invisible in the form; their respective text will be assigned through programming.
  6. The text property of the Push Button widget is set to Calculate Room Rent, the point size of the Label widget representing the Hotel Room Reservation text is increased, and its Bold property is set to make it appear as the header of the application
  7. Save the application with the name reservehotel.ui. The application is shown in the following screenshot:
    The pyuic5 command utility converts the .ui (XML) file into Python code. The generated Python code, reservehotel.py, can be seen in the code bundle of the book.
  8. Create a Python script named computeRoomRent.pyw that imports the code, reservehotel.py, to invoke the user interface design and compute and display the total room rent on the basis of the number of persons and room type selected. The script will also display the date, a number of persons, and room type options selected by the user.
import sys

from PyQt5.QtWidgets import QDialog, QApplication

from reservehotel import *

class MyForm(QDialog):
    def __init__(self):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.roomtypes=['Suite', 'Super Luxury', 'Super Deluxe', 'Ordinary']
        self.addcontent()     
        self.ui.pushButton.clicked.connect(self.computeRoomRent) 
        self.show()

    def addcontent(self):
        for i in self.roomtypes:
          self.ui.comboBox.addItem(i)
     
    def computeRoomRent(self):
        dateselected=self.ui.calendarWidget.selectedDate()
        dateinstring=str(dateselected.toPyDate())
        noOfDays=self.ui.spinBox.value()
        chosenRoomType=self.ui.comboBox.itemText(self.ui.comboBox.currentIndex())
        self.ui.Enteredinfo.setText('Date of reservation: '+dateinstring+ ', Number of days: '+ str(noOfDays) + ' \nand Room type selected: '+ chosenRoomType)
        roomRent=0
        if chosenRoomType=="Suite":
          roomRent=40
        if chosenRoomType=="Super Luxury":
          roomRent=30
        if chosenRoomType=="Super Deluxe":
          roomRent=20
        if chosenRoomType=="Ordinary":
          roomRent=10
        total=roomRent*noOfDays
        self.ui.RoomRentinfo.setText('Room Rent for single day for '+ chosenRoomType +' type is '+ str(roomRent)+ '$. \nTotal room rent is '+ str(total)+ '$')  
 
if __name__=="__main__":    
    app = QApplication(sys.argv)
    w = MyForm()
    w.show()
    sys.exit(app.exec_())

 

How it works...

In this code, you can see that a roomtypes list is defined with four elements: Suite, Super Luxury, Super Deluxe, and Ordinary. To make the elements of the roomtypes list appear as options in the Combo Box widget, the addcontent method is invoked and adds the elements of roomtypes to the Combo Box widget with the addItem() method. Also,

the clicked() signal of the Push Button widget is connected to the computeRoomRent() method, which is invoked when the user selects the push button after selecting the date of the reservation, the number of persons staying, and room type. In the computeRoomRent() method, you fetch the date from Calendar Widget, the number of persons from the Spin Box widget, and the room type from the Combo Box widget, and then display them through an Enteredinfo widget to indicate the options that are selected by the user. Then, the room rent of an individual is determined on the basis of the room type selected and is multiplied by the number of persons to compute the total room rent. The total room rent is then displayed via roomRent, as shown in the following screenshot:

Displaying tabular data using Table Widget

In this recipe, we will learn to display data in tabular format, that is, in the row and column format. We will display the different room types of a hotel and their respective rents per day.

 

Getting ready

Before we begin creating this recipe, let's first understand Table Widget.

 

Table Widget

Table Widget is used for displaying data in tabular format, arranged in rows and columns. Table Widget is an instance of the QTableWidget class and the items that are displayed in the different rows and columns of a table are instances of the QTableWidgetItem class.

Here are the methods provided by the QTableWidget class:

  • setRowCount(): This method is used to define the number of rows you want in Table Widget
  • setColumnCount(): This method is used to define the number of columns required in Table Widget
  • rowCount(): This method returns the number of rows in the table
  • columnCount(): This method returns the number of columns in the table
  • clear(): This method clears the entire table
  • setItem(): This method sets the content for a given row and column of the table

The QTableWidgetItem class

As mentioned earlier, the items displayed in Table Widget are instances of the QTableWidgetItem class. You can display text, images, or any other widgets as items in Table Widget. Here are the methods provided by the QTableWidgetItem class:

  • setFont(): This method sets the font for the text label of the Table Widget item
  • setCheckState(): This method passes the Boolean value True to this method to check the table item and passes the value False to uncheck the Table Widget item
  • checkState(): This method returns the Boolean value as True if the Table Widget item is checked, or otherwise returns False

Let's now create an application to demonstrate how information is displayed with a Table Widget item.

demoTableWidget.py
0.00MB
demoTableWidget.ui
0.00MB

 

 

 

How to do it...

Information displayed in tabular format is more organized, more readable, and more easily comparable than data that is displayed in traditional paragraphs. Here are the steps to make an application that displays data via Table Widget:

  1. Open Qt Designer and create a new application based on the Dialog without Buttons template.
  2. Drag and drop a Table Widget item onto the form.
  3. To assign it the default size of three rows and two columns, from the Property Editor window set the value of rowCount and columnCount to 4 and 2, respectively.
  4. To display the row and column headers, the horizontalHeaderVisible and verticalHeaderVisible properties are already checked by default
  5. Save the application with the name DemoTableWidget.ui. The Table Widget item will appear as shown in the following screenshot:

The pyuic5 command utility is used for generating Python code. The generated Python script, DemoTableWidget.py, can be seen in the source code bundle of this book.

  1. Create a Python script named callTableWidget.pyw that imports the Python code, DemoTableWidget.py, which enables us to invoke the user interface design and displays information in the Table Widget item. The code in the Python script, callTableWidget.pyw, is as shown here:
import sys

from PyQt5.QtWidgets import QDialog, QApplication,QTableWidgetItem
from demoTableWidget import *

class MyForm(QDialog):
    def __init__(self,data):
        super().__init__()
        self.ui = Ui_Dialog()
        self.ui.setupUi(self)
        self.data=data
        self.addcontent()

    def addcontent(self):
        row=0
        for tup in self.data:
            col=0
            for item in tup:
                oneitem=QTableWidgetItem(item)
                self.ui.tableWidget.setItem(row, col, oneitem)
                col+=1
            row+=1
data=[]
data.append(('Suite', '40$'))
data.append(('Super Luxury', '30$'))
data.append(('Super Deluxe', '20$'))
data.append(('Ordinary', '10$'))

                
if __name__=="__main__":    
    app = QApplication(sys.argv)
    w = MyForm(data)
    w.show()
    sys.exit(app.exec_())

 

How it works...

If you want to display information in four rows and two columns of Table Widget, create a list named data that stores four tuples, each of which consists of two elements, roomtypes and roomRent. In the addcontent method, you fetch one tuple at a time from the data list and assign it temporarily to the tup variable. The tup variable contains two elements, room type and room rent. With the help of another for loop, you fetch each element from the tup variable; that is, you fetch room type and room rent and assign them to the item variable. The content of the item variable is then converted into an instance of QTableWidgetItem and assigned to oneitem, which in turn is further assigned to and displayed in Table Widget at a particular row and column position using the setItem method. With the help of nested for loops, you display the information of the data list in Table Widget, as shown in the following screenshot:

'Qt5 Python GUI Programming Cookbook' 카테고리의 다른 글

Understanding Dialogs  (0) 2023.02.28
Understanding OOP Concepts  (0) 2023.02.28
Event Handling - Signals andSlots  (0) 2023.02.27
Creating a User Interface with Qt Components  (0) 2023.02.27
index  (0) 2023.02.27

댓글