首页 > 后端开发 > Golang > 为 macOS 构建市政厅时钟应用程序:综合指南

为 macOS 构建市政厅时钟应用程序:综合指南

WBOY
发布: 2024-09-07 06:34:05
原创
1068 人浏览过

Building a City Hall Clock App for macOS: A Comprehensive Guide

准备好为您的 Mac 构建一个很酷的市政厅时钟应用程序了吗?伟大的!我们将创建一个位于菜单栏中的应用程序,每 15 分钟发出一次提示音,甚至可以计算时间。让我们一步步分解,我将解释代码的每一部分,以便您能够理解发生了什么。

项目概况

我们的市政厅时钟应用程序将:

  • 在 macOS 菜单栏中显示时钟图标
  • 每 15 分钟鸣响一次
  • 在每个小时的顶部敲响小时数
  • 在菜单栏中提供“退出”选项
  • 作为正确的 macOS 应用程序运行,无需打开终端窗口

设置项目

首先,让我们设置我们的项目:

  1. 创建一个新目录:
   mkdir CityHallClock
   cd CityHallClock
登录后复制
  1. 初始化一个新的Go模块:
   go mod init cityhallclock
登录后复制
  1. 安装所需的依赖项:
   go get github.com/getlantern/systray
   go get github.com/faiface/beep
登录后复制

主要代码

现在,让我们创建 main.go 文件并浏览每个函数:

package main

import (
    "bytes"
    "log"
    "os"
    "path/filepath"
    "time"

    "github.com/faiface/beep"
    "github.com/faiface/beep/mp3"
    "github.com/faiface/beep/speaker"
    "github.com/getlantern/systray"
)

var (
    audioBuffer *beep.Buffer
)

func main() {
    initAudio()
    systray.Run(onReady, onExit)
}

// ... (other functions will go here)
登录后复制

让我们分解一下每个功能:

1.main()函数

func main() {
    initAudio()
    systray.Run(onReady, onExit)
}
登录后复制

这是我们的应用程序启动的地方。它做了两件重要的事情:

  1. 调用 initAudio() 来设置我们的铃声。
  2. 运行我们的系统托盘应用程序,告诉它在准备好(onReady)和退出(onExit)时要做什么。

2.initAudio()函数

func initAudio() {
    execPath, err := os.Executable()
    if err != nil {
        log.Fatal(err)
    }
    resourcesPath := filepath.Join(filepath.Dir(execPath), "..", "Resources")
    chimeFile := filepath.Join(resourcesPath, "chime.mp3")

    f, err := os.Open(chimeFile)
    if err != nil {
        log.Fatal(err)
    }
    defer f.Close()

    streamer, format, err := mp3.Decode(f)
    if err != nil {
        log.Fatal(err)
    }
    defer streamer.Close()

    audioBuffer = beep.NewBuffer(format)
    audioBuffer.Append(streamer)

    err = speaker.Init(format.SampleRate, format.SampleRate.N(time.Second/10))
    if err != nil {
        log.Fatal(err)
    }
}
登录后复制

此函数设置我们的音频:

  1. 它会找到我们的应用程序运行的位置并找到铃声文件。
  2. 打开 MP3 文件并对其进行解码。
  3. 创建带有铃声的音频缓冲区。
  4. 初始化音频扬声器。

如果出现任何问题(例如找不到声音文件),它会记录错误并退出。

3.onReady()函数

func onReady() {
    systray.SetIcon(getIcon())
    systray.SetTitle("City Hall Clock")
    systray.SetTooltip("City Hall Clock")

    mQuit := systray.AddMenuItem("Quit", "Quit the app")

    go func() {
        <-mQuit.ClickedCh
        systray.Quit()
    }()

    go runClock()
}
登录后复制

此函数设置我们的菜单栏图标:

  1. 设置图标(使用 getIcon())。
  2. 设置标题和工具提示。
  3. 在菜单中添加“退出”选项。
  4. 单击“退出”选项时开始监听。
  5. 开始运行我们的时钟(在一个单独的 goroutine 中,这样它就不会阻塞)。

4.onExit()函数

func onExit() {
    // Cleanup tasks go here
}
登录后复制

当应用程序退出时调用此函数。我们在这里不做任何事情,但您可以根据需要添加清理任务。

5.runClock()函数

func runClock() {
    ticker := time.NewTicker(time.Minute)
    defer ticker.Stop()

    for {
        select {
        case t := <-ticker.C:
            if t.Minute() == 0 || t.Minute() == 15 || t.Minute() == 30 || t.Minute() == 45 {
                go chime(t)
            }
        }
    }
}
登录后复制

这是我们时钟的“心脏”:

  1. 它创建了一个每分钟“滴答”的股票代码。
  2. 在无限循环中,它每分钟检查一次时间。
  3. 如果是整点或一刻钟,则会触发铃声。

6. chime()函数

func chime(t time.Time) {
    hour := t.Hour()
    minute := t.Minute()

    var chimeTimes int
    if minute == 0 {
        chimeTimes = hour % 12
        if chimeTimes == 0 {
            chimeTimes = 12
        }
    } else {
        chimeTimes = 1
    }

    for i := 0; i < chimeTimes; i++ {
        streamer := audioBuffer.Streamer(0, audioBuffer.Len())
        speaker.Play(streamer)
        time.Sleep(time.Duration(audioBuffer.Len()) * time.Second / time.Duration(audioBuffer.Format().SampleRate))

        if i < chimeTimes-1 {
            time.Sleep(500 * time.Millisecond)  // Wait between chimes
        }
    }
}
登录后复制

此功能播放我们的铃声:

  1. 它计算出鸣响多少次(每刻钟鸣响一次,或整点整点的小时数)。
  2. 然后它会多次播放铃声,并在铃声之间短暂停顿。

7. getIcon()函数

func getIcon() []byte {
    execPath, err := os.Executable()
    if err != nil {
        log.Fatal(err)
    }
    iconPath := filepath.Join(filepath.Dir(execPath), "..", "Resources", "icon.png")

    // Read the icon file
    icon, err := os.ReadFile(iconPath)
    if err != nil {
        log.Fatal(err)
    }

    return icon
}
登录后复制

此函数获取我们的菜单栏图标:

  1. 它找到我们的应用程序正在运行的位置。
  2. 在资源目录中找到图标文件。
  3. 读取图标文件并返回其内容。

创建 macOS 应用程序包

为了使我们的应用程序成为真正的 macOS 公民,我们需要创建一个应用程序包。这涉及创建一个 Info.plist 文件:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>CFBundleExecutable</key>
    <string>CityHallClock</string>
    <key>CFBundleIconFile</key>
    <string>AppIcon</string>
    <key>CFBundleIdentifier</key>
    <string>com.yourcompany.cityhallclock</string>
    <key>CFBundleName</key>
    <string>City Hall Clock</string>
    <key>CFBundlePackageType</key>
    <string>APPL</string>
    <key>CFBundleShortVersionString</key>
    <string>1.0</string>
    <key>CFBundleVersion</key>
    <string>1</string>
    <key>LSMinimumSystemVersion</key>
    <string>10.12</string>
    <key>LSUIElement</key>
    <true/>
    <key>NSHighResolutionCapable</key>
    <true/>
</dict>
</plist>
登录后复制

将其保存为项目目录中的 Info.plist。

添加自定义图标

我们需要两个图标:

  1. 菜单栏图标:创建一个 22x22 像素的 PNG,命名为 icon.png。
  2. 应用程序图标:创建 .icns 文件:
    • 制作尺寸为 16x16 到 1024x1024 像素的图像。
    • 将它们保存在 AppIcon.iconset 中,名称如 icon_16x16.png。
    • 运行:iconutil -c icns AppIcon.iconset

建筑和包装

让我们创建一个构建脚本(build.sh):

#!/bin/bash

# Build the Go application
go build -o CityHallClock

# Create the app bundle structure
mkdir -p CityHallClock.app/Contents/MacOS
mkdir -p CityHallClock.app/Contents/Resources

# Move the executable to the app bundle
mv CityHallClock CityHallClock.app/Contents/MacOS/

# Copy the Info.plist
cp Info.plist CityHallClock.app/Contents/

# Copy the chime sound to Resources
cp chime.mp3 CityHallClock.app/Contents/Resources/

# Copy the menu bar icon
cp icon.png CityHallClock.app/Contents/Resources/

# Copy the application icon
cp AppIcon.icns CityHallClock.app/Contents/Resources/

echo "Application bundle created: CityHallClock.app"
登录后复制

使用 chmod +x build.sh 使其可执行,然后使用 ./build.sh 运行它。

结论

就是这样!您已经为 macOS 构建了功能齐全的市政厅时钟应用程序。您已了解:

  • 使用 Go 创建菜单栏应用
  • 以特定时间间隔播放声音
  • 将 Go 应用程序打包为原生 macOS 应用

请随意扩展这一点。也许添加自定义铃声或不同铃声间隔的首选项。天空才是极限!

您可以在这里找到完整的源代码 https://github.com/rezmoss/citychime

快乐编码,享受你的新时钟!

以上是为 macOS 构建市政厅时钟应用程序:综合指南的详细内容。更多信息请关注PHP中文网其他相关文章!

来源:dev.to
本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板