目錄
簡介
程序
源代碼
GUI
DesktopWife.py
MusicPlayer.py
WeatherGui.py
語音
普通的桌面寵物程序只能動一動,于是我給程序添加了語言,既可以聊天,也可以實現(xiàn)一些自動功能,不如搜索,打開程序什么的。
gui界面都是使用PyQt5開發(fā)的,語音喚醒功能也是使用的第三方庫和api
- import sys
- import os
- from PyQt5.QtGui import QCursor
- from PyQt5.QtGui import QIcon
- from PyQt5.QtGui import QPainterPath
- from PyQt5.QtGui import QRegion
- from PyQt5.QtGui import QPixmap
- from PyQt5.QtCore import Qt
- from PyQt5.QtCore import QRectF
- from PyQt5.QtCore import QTimer
- from PyQt5.QtWidgets import QWidget
- from PyQt5.QtWidgets import QApplication
- from PyQt5.QtWidgets import QLabel
- from PyQt5.QtWidgets import QDesktopWidget
- from PyQt5.QtWidgets import QMenu
- from PyQt5.QtWidgets import QAction
- from PyQt5.QtWidgets import QFileDialog
- from PyQt5.QtWidgets import QMessageBox
- import requests
- import WeatherGui
- import MusicPlayer
- import Tray
- import VoiceToText
- VoiceToText.run()
- """主界面"""
- class DesktopWife(QWidget):
- def __init__(self):
- super(DesktopWife, self).__init__()
- self.UI()
- def UI(self):
- self.Image = QPixmap(".\image\\bg.png")
- self.WindowSize = QDesktopWidget().screenGeometry()
- self.setWindowTitle("DesktopWife")
- self.resize(int(self.Image.width()), int(self.Image.height()))
- self.move(int((self.WindowSize.width() - self.Image.width()) / 2), int((self.WindowSize.height() - self.Image.height()) / 2))
- self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.SubWindow)
- # setAutoFillBackground(True)表示的是自動填充背景,False為透明背景
- self.setAutoFillBackground(False)
- # 窗口透明,窗體空間不透明
- self.setAttribute(Qt.WA_TranslucentBackground, True)
- self.PlayLabel = QLabel(self)
- self.PlayLabel.setPixmap(self.Image)
- self.WindowMessage = QLabel("我好困", self)
- self.WindowMessage.setGeometry(int((self.Image.width() - 80) / 2) + 10, 10, 200, 40)
- self.WindowMessage.setStyleSheet("color: white;")
- self.setContextMenuPolicy(Qt.CustomContextMenu)
- self.customContextMenuRequested.connect(self._WindowMenu)
- self.Timer = QTimer()
- self.Timer.start(5000)
- self.Timer.timeout.connect(self.RandomWindowMessage)
- """右鍵菜單"""
- def _WindowMenu(self):
- self.Menu = QMenu(self)
- self.Menu.setStyleSheet("background-color: black; color: white;")
- self.WeatherForecastQAction = QAction(QIcon(".\image\Button.png"), u"查看天氣", self)
- self.Menu.addAction(self.WeatherForecastQAction)
- self.PlayMusicQAction = QAction(QIcon(".\image\Button.png"), u"播放音樂", self)
- self.Menu.addAction(self.PlayMusicQAction)
- self.StartTray = QAction(QIcon(".\image\\bg.png"), u"退置托盤", self)
- self.Menu.addAction(self.StartTray)
- self.CloseWindowAction = QAction(QIcon(".\image\Quit.png"), u"退出程序", self)
- self.Menu.addAction(self.CloseWindowAction)
- self.WeatherForecastQAction.triggered.connect(self.WeatherForecast)
- self.PlayMusicQAction.triggered.connect(self.MusicPaly)
- self.StartTray.triggered.connect(self.SetTray)
- self.CloseWindowAction.triggered.connect(self.ColseWindowActionEvent)
- self.Menu.popup(QCursor.pos())
- # 圓角
- rect = QRectF(0, 0, self.Menu.width(), self.Menu.height())
- path = QPainterPath()
- path.addRoundedRect(rect, 10, 10)
- polygon = path.toFillPolygon().toPolygon()
- region = QRegion(polygon)
- self.Menu.setMask(region)
- def ColseWindowActionEvent(self):
- VoiceToText._conent = False
- self.close()
- sys.exit()
- """系統(tǒng)托盤"""
- def SetTray(self):
- self._Tray = Tray.TrayIcon(self)
- self._Tray.show()
- self.hide()
- """隨機一詩"""
- # 因為csdn的智障檢測,這里無法查看
- """音樂播放"""
- def MusicPaly(self):
- self.file, _Type = QFileDialog.getOpenFileName(self, u"選擇音樂文件", f"{os.path.split(__file__)[0]}\\music")
- if os.path.isfile(self.file):
- self._MusicPlayGui = MusicPlayer.MusicGui(self.file)
- self._MusicPlayGui.show()
- else:
- QMessageBox.information(self, "提示", f"文件:{self.file} 無法識別")
- """天氣預報"""
- def WeatherForecast(self):
- self.WeatherForecastGUI = WeatherGui.WeatherGUI()
- self.WeatherForecastGUI.show()
- """重寫移動事假,更改鼠標圖標"""
- def mousePressEvent(self, event):
- if event.button() == Qt.LeftButton:
- self.m_flag = True
- self.m_Position = event.globalPos() - self.pos() # 獲取鼠標相對窗口的位置
- event.accept()
- self.setCursor(QCursor(Qt.OpenHandCursor)) # 更改鼠標圖標
- def mouseMoveEvent(self, QMouseEvent):
- if Qt.LeftButton and self.m_flag:
- self.move(QMouseEvent.globalPos() - self.m_Position) # 更改窗口位置
- QMouseEvent.accept()
- def mouseReleaseEvent(self, QMouseEvent):
- self.m_flag = False
- self.setCursor(QCursor(Qt.ArrowCursor))
- if __name__ == '__main__':
- app = QApplication(sys.argv)
- Window = DesktopWife()
- Window.show()
- app.exec_()
- import os
- from PyQt5 import QtMultimedia
- from PyQt5.QtGui import QIcon
- from PyQt5.QtGui import QRegion
- from PyQt5.QtGui import QCursor
- from PyQt5.QtGui import QPainterPath
- from PyQt5.QtCore import Qt
- from PyQt5.QtCore import QUrl
- from PyQt5.QtCore import QSize
- from PyQt5.QtCore import QRectF
- from PyQt5.QtWidgets import QLabel
- from PyQt5.QtWidgets import QSlider
- from PyQt5.QtWidgets import QWidget
- from PyQt5.QtWidgets import QPushButton
- from mutagen import File
- """音樂播放界面"""
- class MusicGui(QWidget):
- def __init__(self, _file):
- super(MusicGui, self).__init__()
- self.file = _file
- self.GetMusicIcon()
- self.UI()
- self.Music = QUrl.fromLocalFile(_file)
- self.Content = QtMultimedia.QMediaContent(self.Music)
- self.player = QtMultimedia.QMediaPlayer()
- self.player.setVolume(100)
- self.player.setMedia(self.Content)
- def UI(self):
- self.setWindowTitle("DesktopWife-MusicPlayGui")
- self.resize(240, 135)
- self.QuitButton = QPushButton(self)
- self.QuitButton.setIcon(QIcon(".\image\MusicQuit.png"))
- self.QuitButton.setIconSize(QSize(200, 200))
- self.QuitButton.setGeometry(208, 10, 20, 20)
- QuitButtonRect = QRectF(0, 0, self.QuitButton.width(), self.QuitButton.height())
- QuitButtonPath = QPainterPath()
- QuitButtonPath.addRoundedRect(QuitButtonRect, 10, 10)
- QuitButtonPolgon = QuitButtonPath.toFillPolygon().toPolygon()
- QuitButtonRegion = QRegion(QuitButtonPolgon)
- self.QuitButton.setMask(QuitButtonRegion)
- self.QuitButton.clicked.connect(self.QuitButtonEvent)
- self.WindowMinimizedButton = QPushButton(self)
- self.WindowMinimizedButton.setIcon(QIcon(".\image\WindowMinimized.png"))
- self.WindowMinimizedButton.setIconSize(QSize(20, 20))
- self.WindowMinimizedButton.setGeometry(180, 10, 20, 20)
- WindowMinimizedButtonRect = QRectF(0, 0, self.WindowMinimizedButton.width(), self.WindowMinimizedButton.height())
- WindowMinimizedButtonPath = QPainterPath()
- WindowMinimizedButtonPath.addRoundedRect(WindowMinimizedButtonRect, 10, 10)
- WindowMinimizedButtonPolgon = QuitButtonPath.toFillPolygon().toPolygon()
- WindowMinimizedButtonRegion = QRegion(WindowMinimizedButtonPolgon)
- self.WindowMinimizedButton.setMask(WindowMinimizedButtonRegion)
- self.WindowMinimizedButton.clicked.connect(self.SetWindowMin)
- self.MusicIconLabel = QPushButton(self)
- self.MusicIconLabel.setGeometry(20, 20, 30, 30)
- self.MusicIconLabel.setStyleSheet("color: blue;")
- if os.path.isfile(".\music\MusicIcon\MusicIcon.jpg"):
- self.MusicIconLabel.setIcon(QIcon(".\music\MusicIcon\MusicIcon.jpg"))
- self.MusicIconLabel.setIconSize(QSize(30, 30))
- else:
- self.MusicIconLabel.setText("無法提取音頻圖片")
- self.MusicIconLabel.setGeometry(20, 20, 120, 30)
- self.MusicNameLabel = QLabel(self)
- self.MusicNameLabel.setGeometry(20, int((self.height() - 30) / 2), 250, 30)
- self.MusicNameLabel.setStyleSheet("font-size:10px;")
- self.MusicNameLabel.setText(os.path.split(self.file)[-1])
- self.volume = QSlider(Qt.Horizontal, self)
- self.volume.setMinimum(0)
- self.volume.setMaximum(100)
- self.volume.setValue(50)
- self.volume.setTickInterval(5)
- self.volume.setTickPosition(QSlider.TicksBelow)
- self.volume.setGeometry(10, 100, 150, 30)
- self.volume.valueChanged.connect(self.VolumeNumber)
- self.VolumeNumberLabel = QLabel(f"{self.volume.value()}", self)
- self.VolumeNumberLabel.setGeometry(175, 100, 20, 20)
- self.PlayButton = QPushButton(self)
- self.PlayButton.setIcon(QIcon(".\image\stop.png"))
- self.PlayButton.setIconSize(QSize(200, 200))
- self.PlayButton.setGeometry(200, 100, 30, 30)
- self.IS_PlayMusic = False
- self.PlayButton.clicked.connect(self.PlayButtonEvent)
- # 圓角
- rect = QRectF(0, 0, self.width(), self.height())
- path = QPainterPath()
- path.addRoundedRect(rect, 10, 10)
- polygon = path.toFillPolygon().toPolygon()
- region = QRegion(polygon)
- self.setMask(region)
- def SetWindowMin(self):
- self.setWindowState(Qt.WindowMinimized)
- def QuitButtonEvent(self):
- self.hide()
- if os.path.isfile(".\music\MusicIcon\MusicIcon.jpg"):
- os.remove(".\music\MusicIcon\MusicIcon.jpg")
- self.player.stop()
- def PlayButtonEvent(self):
- if self.IS_PlayMusic:
- self.PauseMusic()
- else:
- self.PlayMusic()
- def VolumeNumber(self):
- self.VolumeNumberLabel.setText(f"{self.volume.value()}")
- self.player.setVolume(self.volume.value())
- def GetMusicIcon(self):
- self.MusicMutagnFile = File(self.file)
- try:
- self.MusicIconData = self.MusicMutagnFile.tags['APIC:test'].data
- with open(".\music\MusicIcon\MusicIcon.jpg", "wb") as wfp:
- wfp.write(self.MusicIconData)
- except KeyError:
- pass
- def PlayMusic(self):
- self.player.play()
- self.PlayButton.setIcon(QIcon(".\image\play.png"))
- self.PlayButton.setIconSize(QSize(200, 200))
- self.IS_PlayMusic = True
- def PauseMusic(self):
- self.player.pause()
- self.PlayButton.setIcon(QIcon(".\image\stop.png"))
- self.PlayButton.setIconSize(QSize(200, 200))
- self.IS_PlayMusic = False
- """重寫移動事假,更改鼠標圖標"""
- def mousePressEvent(self, event):
- if event.button() == Qt.LeftButton:
- self.m_flag = True
- self.m_Position = event.globalPos() - self.pos() # 獲取鼠標相對窗口的位置
- event.accept()
- self.setCursor(QCursor(Qt.OpenHandCursor)) # 更改鼠標圖標
- def mouseMoveEvent(self, QMouseEvent):
- if Qt.LeftButton and self.m_flag:
- self.move(QMouseEvent.globalPos() - self.m_Position) # 更改窗口位置
- QMouseEvent.accept()
- def mouseReleaseEvent(self, QMouseEvent):
- self.m_flag = False
- self.setCursor(QCursor(Qt.ArrowCursor))
- from PyQt5.QtGui import QIcon
- from PyQt5.QtGui import QCursor
- from PyQt5.QtGui import QRegion
- from PyQt5.QtGui import QPainterPath
- from PyQt5.QtCore import Qt
- from PyQt5.QtCore import QSize
- from PyQt5.QtCore import QRectF
- from PyQt5.QtWidgets import QWidget
- from PyQt5.QtWidgets import QLabel
- from PyQt5.QtWidgets import QPushButton
- import requests
- """天氣查詢界面"""
- class WeatherGUI(QWidget):
- def __init__(self):
- super(WeatherGUI, self).__init__()
- self.setWindowTitle("DesktopWife-WeatherGui")
- self.resize(470, 270)
- # 圓角
- rect = QRectF(0, 0, self.width(), self.height())
- path = QPainterPath()
- path.addRoundedRect(rect, 10, 10)
- polygon = path.toFillPolygon().toPolygon()
- region = QRegion(polygon)
- self.setMask(region)
- self.QuitButton = QPushButton(self)
- self.QuitButton.setIcon(QIcon(".\image\Quit.png"))
- self.QuitButton.setIconSize(QSize(40, 40))
- self.QuitButton.setGeometry(400, 10, 40, 40)
- QuitButtonRect = QRectF(0, 0, self.QuitButton.width(), self.QuitButton.height())
- QuitButtonPath = QPainterPath()
- QuitButtonPath.addRoundedRect(QuitButtonRect, 50, 50)
- QuitButtonPolygon = QuitButtonPath.toFillPolygon().toPolygon()
- QuitButtonRegin = QRegion(QuitButtonPolygon)
- self.QuitButton.setMask(QuitButtonRegin)
- self.QuitButton.clicked.connect(self.hide)
- self.WeatherText = QLabel(self)
- self.WeatherText.setGeometry(int((470 - 300) / 2), int((270 - 200) / 2), 300, 200)
- self.GetWeather()
- def GetWeather(self):
- GET = requests.get("# 因為csdn的智障檢測,這里無法查看")
- if GET.status_code == 200:
- JSON = GET.json()
- INFO = JSON['info']
- Data = f"城市:{JSON['city']}\n時間:{INFO['date']}" \
- + f"\n星期:{INFO['week']}\n天氣:{INFO['type']}" \
- + f"\n{INFO['high']}\n{INFO['low']}\n風向:{INFO['fengxiang']}" \
- + f"\n風級:{INFO['fengli']}\n主人您要:{INFO['tip']}"
- self.WeatherText.setText(Data)
- else:
- return False
- """重寫移動事假,更改鼠標圖標"""
- def mousePressEvent(self, event):
- if event.button() == Qt.LeftButton:
- self.m_flag = True
- self.m_Position = event.globalPos() - self.pos() # 獲取鼠標相對窗口的位置
- event.accept()
- self.setCursor(QCursor(Qt.OpenHandCursor)) # 更改鼠標圖標
- def mouseMoveEvent(self, QMouseEvent):
- if Qt.LeftButton and self.m_flag:
- self.move(QMouseEvent.globalPos() - self.m_Position) # 更改窗口位置
- QMouseEvent.accept()
- def mouseReleaseEvent(self, QMouseEvent):
- self.m_flag = False
- self.setCursor(QCursor(Qt.ArrowCursor))
- import os
- import wave
- import pyaudio
- import speech_recognition
- import speech_recognition as sr
- from threading import Thread
- import requests
- CHUNK = 1024
- FORMAT = pyaudio.paInt16
- CHANNELS = 1
- RATE = 16000
- _conent = True
- def record_and_recog(wave_out_path, TIME=3):
- p = pyaudio.PyAudio()
- stream = p.open(format=FORMAT,
- channels=CHANNELS,
- rate=RATE,
- input=True,
- frames_per_buffer=CHUNK)
- wf = wave.open(wave_out_path, 'wb')
- wf.setnchannels(CHANNELS)
- wf.setsampwidth(p.get_sample_size(FORMAT))
- wf.setframerate(RATE)
- for _ in range(0, int(RATE / CHUNK * TIME)):
- data = stream.read(CHUNK)
- wf.writeframes(data)
- stream.stop_stream()
- stream.close()
- p.terminate()
- wf.close()
- return wave_out_path
- def TTS(Test: str):
- GET = requests.get(f"https://tts.youdao.com/fanyivoice?word={Test}&le=zh&keyfrom=speaker-target")
- if GET.status_code == 200:
- with open(".\\out.mp3", "wb") as wfp:
- wfp.write(GET.content)
- wfp.close()
- FFplay = os.popen(f"cd {os.path.split(__file__)[0]} && ffplay out.mp3 -noborder -nodisp -autoexit")
- FFplay.readlines()
- return True
- else:
- return False
- def Scanning(Path="C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\"):
- _DIRList = []
- _File = []
- for paths, dirs, files in os.walk(Path):
- if dirs:
- for dir in dirs:
- _DIRList.append(paths+"\\"+dir)
- if files:
- for file in files:
- _File.append(paths+"\\"+file)
- return _File
- def GoogleTranslate():
- global _conent
- while _conent:
- Rec = sr.Recognizer()
- with sr.AudioFile(record_and_recog(".\\test.wav")) as source:
- audio = Rec.record(source)
- try:
- GoogleTranslateText = Rec.recognize_google(audio, language="zh-CN")
- except speech_recognition.UnknownValueError:
- continue
- print(GoogleTranslateText)
- if "小雨" in GoogleTranslateText or "小宇" in GoogleTranslateText:
- TTS("主人我在聽,請您下達命令")
- NewRec = sr.Recognizer()
- with sr.AudioFile(record_and_recog(".\\test.wav")) as Newsource:
- NewAudio = NewRec.record(Newsource)
- try:
- Text = Rec.recognize_google(NewAudio, language="zh-CN")
- except speech_recognition.UnknownValueError:
- continue
- print(Text)
- # 因為csdn智障檢測,這里無法查看
- elif "打開命令行" in Text:
- TTS("好的, 主人")
- os.popen(f"start cmd")
- TTS("已為您打開命令行")
- elif "關閉語音功能" in Text or "關閉語音" in Text:
- TTS("好的,主人 下次再見")
- break
- elif "打開" in Text:
- TTS("好的, 主人")
- ISSTART = False
- for _Path in Scanning():
- if Text.strip("打開") == os.path.split(_Path)[-1].split(".")[0]:
- os.popen(f'"{_Path}"')
- print(_Path)
- TTS(f"已為您打開 {Text.strip('打開')}")
- ISSTART = True
- break
- if ISSTART:
- continue
- else:
- TTS(f"主人未找到 {Text.strip('打開')}")
- elif "關機" in Text:
- TTS("主人是否確定要關機呢?")
- shotdownRrc = sr.Recognizer()
- with sr.AudioFile(record_and_recog(".\\out.mp3")) as shotdowndata:
- shotdownAudio = shotdownRrc.record(shotdowndata)
- try:
- ISSHOTDOWN = Rec.recognize_google(shotdownAudio, language="zh-CN")
- except speech_recognition.UnknownValueError:
- continue
- if ISSHOTDOWN in ["是", "是的", "沒錯", "要"]:
- TTS("好的, 主人好好學習呀!")
- os.popen("shutdown -s -t 1")
- elif ISSHOTDOWN in ["否", "不", "不要", "不關機"]:
- TTS("好的, 不進行關機")
- else:
- TTS("主人,我沒聽懂")
- else:
- # 因為csdn的智障檢測,這里無法查看
- if GET.status_code == 200:
- try:
- TTS(str(GET.json()['data']['info']['text']).replace("小思", "小雨"))
- except TypeError:
- continue
- def run():
- Start = Thread(target=GoogleTranslate)
- Start.start()
- # Start.join()
使用 Python 實現(xiàn)一個可以語音交流的桌面寵物
聯(lián)系客服