Notebook

これは日々の作業を通して学んだことや毎日の生活で気づいたことをを記録しておく備忘録である。

HTML ファイル生成日時: 2025/04/03 13:41:35.024 (台灣標準時)

tkinter.ttk を使った GUI のあるプログラムの作成について

これまで GUI のあるプログラムを書いたことがほとんどなかったので、どの ように書けばよいのか調べてみたでござる。 tkinter.ttk というものがある ようなので、そこれを使ってみることとしたでござる。試しに、 LST (Local Sidereal Time) clock を作ってみたでござる。ソースコードは以下の通りで ござる。


#!/usr/pkg/bin/python3.13

#
# Time-stamp: <2025/03/23 16:55:48 (UT+08:00) daisuke>
#

# importing argparse module
import argparse

# importing astropy module
import astropy.time
import astropy.units

# importing datetime module
import datetime

# importing sys module
import sys

# importing tkinter module
import tkinter
import tkinter.ttk

# initialising a parser
parser = argparse.ArgumentParser (description='LST Clock')

# adding arguments
parser.add_argument ('-s', '--site', default='Lulin', \
                     help='Observatory site name (default: Lulin)')
parser.add_argument ('-l', '--longitude', default='120:52:21.5', \
                     help='Longitude in ddd:mm:ss.s format')
parser.add_argument ('-b', '--latitude', default='+23:28:10.0', \
                     help='Latitude in [+/-]dd:mm:ss.s format')
parser.add_argument ('-a', '--altitude', type=float, default=2862.0, \
                     help='Altitude above sea level in metre')
parser.add_argument ('-z', '--timezone', type=float, default=8.0, \
                     help='offset from UT in hour')

# parsing arguments
args = parser.parse_args ()

# command-line arguments
site_name   = args.site
longitude   = args.longitude
latitude    = args.latitude
altitude_m  = args.altitude
timezone_hr = args.timezone

# class AstroTime
class AstroTime:
    def __init__ (self, site, lon, lat, altitude, tz):
        if ( (site == '') or (lon == '') or (lat == '') or (altitude == '') \
             or (tz == '') ):
            print (f'ERROR: missing information')
            sys.exit (0)
        self.site     = site
        self.lon      = lon
        self.lat      = lat
        self.altitude = altitude
        self.tz       = tz

    # method to find date/time in UTC
    def find_utcnow (self):
        # date/time
        utc_now  = datetime.datetime.now (datetime.UTC)
        utc_YYYY = utc_now.year
        utc_MM   = utc_now.month
        utc_DD   = utc_now.day
        utc_hh   = utc_now.hour
        utc_mm   = utc_now.minute
        utc_ss   = utc_now.second
        # utc in YYYY-MM-DD
        utc_YYYYMMDD = f'{utc_YYYY:04d}-{utc_MM:02d}-{utc_DD:02d}'
        # utc in hh:mm:ss format
        utc_hhmmss = f'{utc_hh:02d}:{utc_mm:02d}:{utc_ss:02d}'
        # return utc in hh:mm:ss format
        return (utc_YYYYMMDD, utc_hhmmss)

    # method to find local time
    def find_localtime (self):
        # finding local time
        offset  = datetime.timedelta (hours=self.tz)
        tz      = datetime.timezone (offset)
        lt_now  = datetime.datetime.now (tz)
        lt_YYYY = lt_now.year
        lt_MM   = lt_now.month
        lt_DD   = lt_now.day
        lt_hh   = lt_now.hour
        lt_mm   = lt_now.minute
        lt_ss   = lt_now.second
        # localtime in YYYY-MM-DD
        lt_YYYYMMDD = f'{lt_YYYY:04d}-{lt_MM:02d}-{lt_DD:02d}'
        # localtime in hh:mm:ss format
        lt_hhmmss = f'{lt_hh:02d}:{lt_mm:02d}:{lt_ss:02d}'
        # return localtime in hh:mm:ss format
        return (lt_YYYYMMDD, lt_hhmmss)

    # method to find local sidereal time
    def find_lst (self):
        (utc_YYYYMMDD, utc_hhmmss) = astrotime.find_utcnow ()
        utc_str = f'{utc_YYYYMMDD} {utc_hhmmss}'
        t_astropy = astropy.time.Time (utc_str, format='iso', scale='utc', \
                                       location=(self.lon, self.lat) )
        lst = t_astropy.sidereal_time ('apparent')
        lst_hhmmss = f'{int (lst.hms.h):02d}:{int (lst.hms.m):02d}:{int (lst.hms.s):02d}'
        return (lst_hhmmss)

# function to update label
def update_time ():
    (utc_YYYYMMDD, utc_hhmmss) = astrotime.find_utcnow ()
    (lt_YYYYMMDD, lt_hhmmss)   = astrotime.find_localtime ()
    (lst_hhmmss)               = astrotime.find_lst ()
    label_utc_YYYYMMDD.configure (text=f'Date (UTC): {utc_YYYYMMDD}')
    label_utc_hhmmss.configure (text=f'Time (UTC): {utc_hhmmss}')
    label_lt_YYYYMMDD.configure (text=f'Date (Local): {lt_YYYYMMDD}')
    label_lt_hhmmss.configure (text=f'Time (Local): {lt_hhmmss}')
    label_lst_hhmmss.configure (text=f'LST: {lst_hhmmss}')
    gui.after (300, update_time)

# main routine
if (__name__ == '__main__'):
    # making AstroTime object
    astrotime = AstroTime (site_name, longitude, latitude, altitude_m, \
                           timezone_hr)
    # root window of GUI
    gui = tkinter.Tk ()
    # style
    style = tkinter.ttk.Style ()
    style.configure ('TButton', font=('Helvetica', 32))
    # frame
    frame = tkinter.ttk.Frame (gui, padding=10)
    frame.grid ()
    # date/time
    (utc_YYYYMMDD, utc_hhmmss) = astrotime.find_utcnow ()
    (lt_YYYYMMDD, lt_hhmmss)   = astrotime.find_localtime ()
    (lst_hhmmss)               = astrotime.find_lst ()
    # adding components
    label_title = tkinter.ttk.Label (frame, \
                                     padding=8, \
                                     text=f'LST Clock', \
                                     font=('Helvetica', 64))
    label_title.grid (column=0, row=0, columnspan=2)

    label_siteinfo = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Site Information: {astrotime.site}', \
        font=('Helvetica', 48)
    )
    label_siteinfo.grid (column=0, row=1, columnspan=2)
    label_lon = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Longitude: {astrotime.lon}', \
        font=('Helvetica', 32)
    )
    label_lon.grid (column=0, row=2)
    label_lat = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Latitude: {astrotime.lat}', \
        font=('Helvetica', 32)
    )
    label_lat.grid (column=1, row=2)
    label_altitude = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Altitude: {astrotime.altitude}-m', \
        font=('Helvetica', 32)
    )
    label_altitude.grid (column=0, row=3)
    label_timezone = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Timezone: {astrotime.tz:+4.1f}-hr', \
        font=('Helvetica', 32)
    )
    label_timezone.grid (column=1, row=3)

    label_time = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Time', \
        font=('Helvetica', 48)
    )
    label_time.grid (column=0, row=4, columnspan=2)
    label_utc_YYYYMMDD = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Date (UTC): {utc_YYYYMMDD}', \
        font=('Helvetica', 32)
    )
    label_utc_YYYYMMDD.grid (column=0, row=5)
    label_utc_hhmmss = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Time (UTC): {utc_hhmmss}', \
        font=('Helvetica', 32)
    )
    label_utc_hhmmss.grid (column=1, row=5)
    label_lt_YYYYMMDD = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Date (Local): {lt_YYYYMMDD}', \
        font=('Helvetica', 32)
    )
    label_lt_YYYYMMDD.grid (column=0, row=6)
    label_lt_hhmmss = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'Time (Local): {lt_hhmmss}', \
        font=('Helvetica', 32)
    )
    label_lt_hhmmss.grid (column=1, row=6)
    label_lst_hhmmss = tkinter.ttk.Label (
        frame, \
        padding=8, \
        text=f'LST: {lst_hhmmss}', \
        font=('Helvetica', 32)
    )
    label_lst_hhmmss.grid (column=1, row=7)

    button_quit = tkinter.ttk.Button (
        frame, \
        command=gui.destroy, \
        text=f'Quit', \
        style='TButton'
    )
    button_quit.grid (column=0, row=8, columnspan=2)

    update_time ()
    gui.mainloop ()

以下のように実行してみたでござる。


% python3.13 xlst.py &

以下のようなウィンドウが表示されるでござる。

fig_202503/xlst.png

LST の計算には Astropy を使っているので問題ないはずでござるが、 XEphem と比べてみたでござる。大きな違いはないようでござる。

参考文献



Frequently accessed files

  1. Computer___Python/20220518_0.html
  2. Computer___Network/20230726_00.html
  3. Misc___Taiwan/20240207_00.html
  4. Computer___Network/20230516_00.html
  5. Computer___FreeBSD/20220621_0.html
  6. Computer___Network/20230508_00.html
  7. Computer___Network/20240130_00.html
  8. Computer___Python/20220715_0.html
  9. Food___Taiwan/20220429_0.html
  10. Computer___TeX/20231107_00.html
  11. Computer___NetBSD/20230119_00.html
  12. Computer___Network/20240416_00.html
  13. Computer___Python/20220410_0.html
  14. Computer___Python/20221013_0.html
  15. Computer___NetBSD/20220817_3.html
  16. Computer___Network/20220413_1.html
  17. Computer___Debian/20210223_1.html
  18. Computer___Python/20240101_00.html
  19. Misc___Japan/20240610_00.html
  20. Computer___Python/20210124_0.html
  21. Computer___NetBSD/20220818_1.html
  22. Computer___NetBSD/20220428_0.html
  23. Computer___NetBSD/20240101_02.html
  24. Science___Math/20220420_0.html
  25. Computer___TeX/20230726_01.html
  26. Computer___TeX/20230503_00.html
  27. Science___Astronomy/20220503_0.html
  28. Computer___NetBSD/20230515_00.html
  29. Computer___NetBSD/20220808_0.html
  30. Computer___NetBSD/20240101_03.html


HTML file generated by Kinoshita Daisuke.