Python简单GUI程序示例

本文介绍了使用Python实现的四个简单应用:记事本功能,图形绘制工具,互动猜数游戏及视频播放器,展示了基础GUI编程的实用性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Python简单GUI程序示例

参考或取自网络,包括:一、记事本;二、简单画图;三、猜数游戏;四、视频播放器

一、记事本

源码

#python简易记事本
from tkinter import *
from tkinter import messagebox
from tkinter import filedialog
import os
 
filename=''   #文件名,全局变量
def about():
    messagebox.showinfo('提示','这是一个消息框')
def openFile():
    global filename   #使用全局变量
    filename=filedialog.askopenfilename(defaultextension='.txt')   #打开文件,默认扩展名是xtxt
    if filename=='':   #如果没有选择
        filename=None
    else:
        root.title('FileName:'+os.path.basename(filename))   #将文件名显示在标题栏中
        textPad.delete(1.0,END)   #删除文本框中原有内容
        f=open(filename,'r',encoding='UTF-8')   #获取文件中内容
        textPad.insert(1.0,f.read())   #显示到文本框
        f.close()
def saveOtherFile():
    global filename
    f=filedialog.asksaveasfilename(initialfile='未命名.txt',defaultextension='.txt')   #保存文件
    filename=f
    root.title('FileName:' + os.path.basename(filename))
    fh=open(f,'w',encoding='UTF-8')   #只写方式打开文件
    msg=textPad.get(1.0,END)   #从文本框中获取内容
    fh.write(msg)
    fh.close()
 
root=Tk()   #设置菜单栏
root.title('记事本')
root.geometry('500x500+100+100')   #widthxheight+x+y
menubar=Menu(root)
root.config(menu=menubar)
filemenu=Menu(menubar)   #第一个菜单栏
filemenu.add_command(label='打开',accelerator='Ctrl+N',command=openFile)
filemenu.add_command(label='保存',accelerator='Ctrl+T',command=saveOtherFile)
menubar.add_cascade(label='文件',menu=filemenu)
 
aboutmenu=Menu(menubar)
aboutmenu.add_command(label='关于',accelerator='Ctrl+Y',command=about)
menubar.add_cascade(label='帮助',menu=aboutmenu)
 
status=Label(root,text='Ln20',bd=1,relief=SUNKEN,anchor=W)   #底部状态栏
status.pack(side=BOTTOM,fill=X)
 
lnlabel=Label(root,width=2,bg='antique white')   #左边边界栏
lnlabel.pack(side=LEFT,fill=Y)
 
textPad=Text(root,undo=True)   #设置文本框
textPad.pack(expand=YES,fill=BOTH)
 
scroll=Scrollbar(textPad)   #右边进度条栏
textPad.config(yscrollcommand=scroll.set)
scroll.config(command=textPad.yview)
scroll.pack(side=RIGHT,fill=Y)
 
root.mainloop()

运行效果:

二、简单画图

# 画图程序
import os
import tkinter
import tkinter.simpledialog
import tkinter.colorchooser
import tkinter.filedialog
from PIL import Image
from PIL import ImageGrab

def openItem():
    global img
    filename=tkinter.filedialog.askopenfilename(title="Open",filetypes=[('Image','*.png *.gif')])
    if filename:
        img=tkinter.PhotoImage(file=filename)
        canvas.create_image(400,300,image=img)
        
def saveItem():
    
    saveX=int(root.winfo_rootx())
    saveY=int(root.winfo_rooty())
    saveW=root.winfo_width()
    saveH=root.winfo_height()
    im=ImageGrab.grab((saveX,saveY,saveX+saveW,saveY+saveH))      
    filename=tkinter.filedialog.asksaveasfilename(title='Save',filetypes=[('Image','*.png *.gif')])
    if not filename:
        return
    try:
        if filename[filename.index('.'):] in ['.png','.gif']==False:
            filename+='.png'
    except:
        filename+='.png'
    im.save(filename)

def clearItem():
    for i in canvas.find_all():
        canvas.delete(i)
        
def curveType():   
    penType.set(1)

def lineType():
    penType.set(2)

def rectangleType():
    penType.set(3)
    
def textType():
    global userText
    userText=tkinter.simpledialog.askstring(title="Please input your words", prompt='')
    penType.set(4)
    
def eraseType():
    penType.set(5)

def chooseForeColor():
    global foreColor    
    foreColor=tkinter.colorchooser.askcolor()[1]

def chooseBackColor():
    global backColor
    backColor=tkinter.colorchooser.askcolor()[1]

def onClickLeft(event):
    global userText
    canDraw.set(1)
    X.set(event.x)
    Y.set(event.y)
    if penType.get()==4:
        canvas.create_text(event.x,event.y,text=userText)
        
def onMoveLeft(event):
    global lastPaint,foreColor,backColor
    if canDraw.get()==0:
        return
    if penType.get()==1:        #绘制曲线
        canvas.create_line(X.get(),Y.get(),event.x,event.y,fill=foreColor)
        X.set(event.x)
        Y.set(event.y)
    elif penType.get()==2:      #绘制直线(预览)
        try:
            canvas.delete(lastPaint)
        except:
            pass
        lastPaint=canvas.create_line(X.get(),Y.get(),event.x,event.y,fill=foreColor)
    elif penType.get()==3:      #绘制矩形(预览)
        try:
            canvas.delete(lastPaint)
        except:
            pass
        lastPaint=canvas.create_rectangle(X.get(),Y.get(),event.x,event.y,fill=backColor,outline=foreColor)
    elif penType.get()==5:      #橡皮擦
        canvas.create_rectangle(event.x-5,event.y-5,event.x+5,event.y+5,fill=backColor,outline=backColor)

def onReleaseLeft(event):
    global lastPaint,foreColor,backColor
    lastPaint=0  
    if penType.get()==2:         #抬起左键画直线
        canvas.create_line(X.get(),Y.get(),event.x,event.y,fill=foreColor)
    elif penType.get()==3:      #抬起左键就画矩形
        canvas.create_rectangle(X.get(),Y.get(),event.x,event.y,fill=backColor,outline=foreColor)
    canDraw.set(0)
    
def onReleaseRight(event):
    menu.post(event.x_root, event.y_root)

root=tkinter.Tk()
root.title("Paint")
root.geometry("800x600+280+50")

lastPaint=0
userText=""
foreColor='black'
backColor='white'
X=tkinter.IntVar(value=0)
Y=tkinter.IntVar(value=0)
canDraw=tkinter.IntVar(value=0)     #能否画图,1:能,0:不能
penType=tkinter.IntVar(value=1)     #画笔类型,1:曲线,2:直线,3:矩形,4:文本,5:橡皮擦

menu=tkinter.Menu(root,tearoff=0)
subMenu=tkinter.Menu(menu,tearoff=0)

img=tkinter.PhotoImage()
canvas=tkinter.Canvas(root,bg='white',width=800,height=600)
canvas.create_image(800,600,image=img)

menu.add_command(label='Open',command=openItem)
menu.add_command(label='Save as',command=saveItem)
menu.add_separator()
subMenu.add_command(label='Curve',command=curveType)
subMenu.add_command(label='Line',command=lineType)
subMenu.add_command(label='Rectangle',command=rectangleType)
subMenu.add_command(label='Text',command=textType)
subMenu.add_command(label='Erase',command=eraseType)
menu.add_cascade(label='Pen Type',menu=subMenu)
menu.add_separator()
menu.add_command(label='Foreground Color',command=chooseForeColor)
menu.add_command(label='Bakckground Color',command=chooseBackColor)
menu.add_separator()
menu.add_command(label='Clear',command=clearItem)

canvas.bind('<Button-1>', onClickLeft)
canvas.bind('<B1-Motion>',onMoveLeft)
canvas.bind('<ButtonRelease-1>',onReleaseLeft)
canvas.bind('<ButtonRelease-3>',onReleaseRight)
canvas.pack(fill=tkinter.BOTH,expand=tkinter.YES)

root.mainloop()

 运行效果:

 三、猜数游戏

#猜数游戏
import tkinter
import tkinter.messagebox
from tkinter.simpledialog import askinteger
import random

def init():
    entryNum['state'] = "disabled"
    btnConfirm['state'] = "disabled"

def confirm():
    global guessNum
    global count
    count[0] += 1
    t = guessNum - int(varNum.get())
    if(t == 0):  # 猜对了
        #tkinter.messagebox.showinfo(title="祝贺", message="你赢了!")
        count[1] += 1
        btnConfirm['state'] = "disabled"
        mess2 = tkinter.Label(root,text="你赢了!猜的次数:" + str(count[0])).place(x=20, y=30, width=200, height=20)  #显示标签
    elif(t > 0):  # 猜小了
        #tkinter.messagebox.showinfo(title="提示", message="猜小了!")
        mess2 = tkinter.Label(root,text="猜小了" ).place(x=20, y=30, width=200, height=20)  #显示标签
        count[2] += 1
    else:  # 猜大了
        #tkinter.messagebox.showinfo(title="提示", message="猜大了!")
        mess2 = tkinter.Label(root,text="猜大了" ).place(x=20, y=30, width=200, height=20)  #显示标签
        count[2] += 1
      

def startGuess():
    global count
    global guessNum
    global minNum
    global maxNum
    guessNum = random.randint(minNum, maxNum)
    mess2 = tkinter.Label(root,text="范围:" +str(minNum)+"~"+str(maxNum)).place(x=20, y=30, width=200, height=20)  #显示标签
    print(guessNum)
    count = [0, 0, 0]
    entryNum['state'] = "normal"
    btnConfirm['state'] = "normal"
    
def setProperty():
    global minNum
    global maxNum
    while True:
        try:
            t = askinteger("设置最小值",'设置最小整数(>0)',initialvalue=1)
            if t != None:
                assert t>0
                minNum=t
                break
        except:
            pass
    while True:
        try:
            t = askinteger("设置最大值",'设置最大整数(>'+str(minNum)+')',initialvalue=minNum+10)
            if t != None:
                assert t>minNum
                maxNum=t
                break
        except:
            pass
    changeNum()
    btnConfirm['state'] = "disabled"
    mess2 = tkinter.Label(root,text="范围:" +str(minNum)+"~"+str(maxNum)).place(x=20, y=30, width=200, height=20)  #显示标签
   

def changeNum():
    global guessNum
    global minNum
    global maxNum
    guessNum = random.randint(minNum, maxNum)

def closeWindow():
    global count
    #tkinter.messagebox.showinfo("成绩", "次数:" + str(count[0]) + "   Right:" + str(count[1]) + "   Wrong:" + str(count[2]))
    root.destroy()

minNum = 1
maxNum = 100
guessNum = 0
count = [0, 0, 0]  # 分别为:猜测次数,正确次数,错误次数

root = tkinter.Tk()
root.title("Guess Number")
root.resizable(False, False)
root.geometry("400x100+480+320")

mess = tkinter.Label(root, text="请输入一个整数:")
mess.place(x=20, y=10, width=200, height=20)

mess2 = tkinter.Label(root,text="提示").place(x=20, y=30, width=200, height=20)  #显示标签

varNum = tkinter.StringVar(root, value='0')
entryNum = tkinter.Entry(root, width=80, textvariable=varNum)
entryNum.place(x=220, y=10, width=60, height=20)

btnConfirm = tkinter.Button(root, text='确认', command=confirm)
btnConfirm.place(x=290, y=10, width=70, height=20)

#btnChange = tkinter.Button(root, text="更换数字", command=changeNum)
#btnChange.place(x=20, y=50, width=90, height=20)

btnStart = tkinter.Button(root, text='[重新]开始', command=startGuess)
btnStart.place(x=210, y=50, width=70, height=20)

btnSet = tkinter.Button(root, text='设置范围', command=setProperty)
btnSet.place(x=125, y=50, width=70, height=20)


init()
root.protocol("WM_DELETE_WINDOW", closeWindow)
root.mainloop()

运行效果:

四、视频播放器

注意事项

1)需要使用pip安装Python扩展包(模块)PyQt5;

2)PyQt5 的多媒体模块QtMultimedia本身不提供任何的编码和解码功能,所以Qt的多媒体模块需要依赖平台(操作系统)支持那些编码和解码格式。 
若想播放MP4等格式需要下载安装解码器K-Lite_Codec_Pack_1680_Basic.exe (下载地址http://www.codecguide.com/download_k-lite_codec_pack_basic.htm

源码如下:

#
from PyQt5.QtWidgets import *
from PyQt5.QtMultimedia import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5 import QtCore, QtGui, QtWidgets
import sys
from PyQt5.QtCore import *
from PyQt5.QtWidgets import QSlider
from PyQt5.QtMultimediaWidgets import QVideoWidget
from PyQt5.QtCore import *
 
 
class myVideoWidget(QVideoWidget):
    doubleClickedItem = pyqtSignal(str)  # 创建双击信号
 
    def __init__(self, parent=None):
        super(QVideoWidget, self).__init__(parent)
 
 
    def mouseDoubleClickEvent(self, QMouseEvent):     #双击事件
        self.doubleClickedItem.emit("double clicked")
 
 
 
class myVideoSlider(QSlider):
    ClickedValue = pyqtSignal(int)
 
    def __init__(self, father):
        super().__init__(Qt.Horizontal, father)
 
    def mousePressEvent(self, QMouseEvent):     #单击事件
        super().mousePressEvent(QMouseEvent)
        value = QMouseEvent.localPos().x()
        # self.setValue(int(value)/9)
        value = round(value/self.width()*self.maximum())  # 根据鼠标点击的位置和slider的长度算出百分比
        self.ClickedValue.emit(value)
 
     
 
class myMainWindow(QMainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(615, 404)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.wgt_video = myVideoWidget(self.centralwidget)
        self.wgt_video.setMinimumSize(QtCore.QSize(410, 200))
        self.wgt_video.setMaximumSize(QtCore.QSize(16777215, 16777215))
        palette = QtGui.QPalette()
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Active, QtGui.QPalette.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(255, 255, 255))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Inactive, QtGui.QPalette.Window, brush)
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Base, brush)
        brush = QtGui.QBrush(QtGui.QColor(0, 0, 0))
        brush.setStyle(QtCore.Qt.SolidPattern)
        palette.setBrush(QtGui.QPalette.Disabled, QtGui.QPalette.Window, brush)
        self.wgt_video.setPalette(palette)
        self.wgt_video.setAutoFillBackground(True)
        self.wgt_video.setObjectName("wgt_video")
        self.gridLayout.addWidget(self.wgt_video, 0, 0, 1, 1)
        self.sld_video = myVideoSlider(self.centralwidget)
        self.sld_video.setMinimumSize(QtCore.QSize(410, 0))
        self.sld_video.setMaximumSize(QtCore.QSize(16777215, 20))
        self.sld_video.setMaximum(100)
        self.sld_video.setOrientation(QtCore.Qt.Horizontal)
        self.sld_video.setObjectName("sld_video")
        self.gridLayout.addWidget(self.sld_video, 1, 0, 1, 1)
        self.lab_video = QtWidgets.QLabel(self.centralwidget)
        self.lab_video.setMaximumSize(QtCore.QSize(16777215, 50))
        self.lab_video.setObjectName("lab_video")
        self.gridLayout.addWidget(self.lab_video, 1, 1, 1, 1)
        self.splitter = QtWidgets.QSplitter(self.centralwidget)
        self.splitter.setOrientation(QtCore.Qt.Horizontal)
        self.splitter.setObjectName("splitter")
        self.btn_open = QtWidgets.QPushButton(self.splitter)
        self.btn_open.setMaximumSize(QtCore.QSize(100, 25))
        self.btn_open.setObjectName("btn_open")
        self.btn_play = QtWidgets.QPushButton(self.splitter)
        self.btn_play.setMaximumSize(QtCore.QSize(100, 25))
        self.btn_play.setObjectName("btn_play")
        self.btn_stop = QtWidgets.QPushButton(self.splitter)
        self.btn_stop.setMaximumSize(QtCore.QSize(100, 25))
        self.btn_stop.setObjectName("btn_stop")
        self.sld_audio = QtWidgets.QSlider(self.splitter)
        self.sld_audio.setMinimumSize(QtCore.QSize(100, 0))
        self.sld_audio.setMaximumSize(QtCore.QSize(150, 20))
        self.sld_audio.setProperty("value", 99)
        self.sld_audio.setOrientation(QtCore.Qt.Horizontal)
        self.sld_audio.setObjectName("sld_audio")
        self.lab_audio = QtWidgets.QLabel(self.splitter)
        self.lab_audio.setObjectName("lab_audio")
        self.btn_cast = QtWidgets.QPushButton(self.splitter)
        self.btn_cast.setObjectName("btn_cast")
        self.gridLayout.addWidget(self.splitter, 2, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.menubar = QtWidgets.QMenuBar(MainWindow)
        self.menubar.setGeometry(QtCore.QRect(0, 0, 615, 23))
        self.menubar.setObjectName("menubar")
        MainWindow.setMenuBar(self.menubar)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)
 
 
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
 
        self.lab_video.setText("0%")
        self.btn_open.setText("打开视频文件")
        self.btn_play.setText("播放")
        self.btn_stop.setText("暂停")
        self.lab_audio.setText("volume:100%")
        self.btn_cast.setText("截图")
 
        self.sld_video_pressed=False  #判断当前进度条识别否被鼠标点击
        self.videoFullScreen = False   # 判断当前widget是否全屏
        self.videoFullScreenWidget = myVideoWidget()   # 创建一个全屏的widget
        self.player = QMediaPlayer()
        self.player.setVideoOutput(self.wgt_video)  # 视频播放输出的widget,就是上面定义的
        self.btn_open.clicked.connect(self.openVideoFile)   # 打开视频文件按钮
        self.btn_play.clicked.connect(self.playVideo)       # play
        self.btn_stop.clicked.connect(self.pauseVideo)       # pause
        self.btn_cast.clicked.connect(self.castVideo)        # 视频截图
        self.player.positionChanged.connect(self.changeSlide)      # change Slide
        self.videoFullScreenWidget.doubleClickedItem.connect(self.videoDoubleClicked)  #双击响应
        self.wgt_video.doubleClickedItem.connect(self.videoDoubleClicked)   #双击响应
        self.sld_video.setTracking(False)
        self.sld_video.sliderReleased.connect(self.releaseSlider)
        self.sld_video.sliderPressed.connect(self.pressSlider)
        self.sld_video.sliderMoved.connect(self.moveSlider)   # 进度条拖拽跳转
        self.sld_video.ClickedValue.connect(self.clickedSlider)  # 进度条点击跳转
        self.sld_audio.valueChanged.connect(self.volumeChange)  # 控制声音播放
        self.btn_cast.hide()
 
    def castVideo(self):
        screen = QGuiApplication.primaryScreen()
        cast_jpg = './'+QDateTime.currentDateTime().toString("yyyy-MM-dd hh-mm-ss-zzz")+'.jpg'
        screen.grabWindow(self.wgt_video.winId()).save(cast_jpg)
 
    def volumeChange(self, position):
        volume= round(position/self.sld_audio.maximum()*100)
        print("vlume %f" %volume)
        self.player.setVolume(volume)
        self.lab_audio.setText("volume:"+str(volume)+"%")
 
    def clickedSlider(self, position):
        if self.player.duration() > 0:  # 开始播放后才允许进行跳转
            video_position = int((position / 100) * self.player.duration())
            self.player.setPosition(video_position)
            self.lab_video.setText("%.2f%%" % position)
        else:
            self.sld_video.setValue(0)
 
    def moveSlider(self, position):
        self.sld_video_pressed = True
        if self.player.duration() > 0:  # 开始播放后才允许进行跳转
            video_position = int((position / 100) * self.player.duration())
            self.player.setPosition(video_position)
            self.lab_video.setText("%.2f%%" % position)
 
    def pressSlider(self):
        self.sld_video_pressed = True
        print("pressed")
 
    def releaseSlider(self):
        self.sld_video_pressed = False
 
    def changeSlide(self, position):
        if not self.sld_video_pressed:  # 进度条被鼠标点击时不更新
            self.vidoeLength = self.player.duration()+0.1
            self.sld_video.setValue(round((position/self.vidoeLength)*100))
            self.lab_video.setText("%.2f%%" % ((position/self.vidoeLength)*100))
 
    def openVideoFile(self):
        self.player.setMedia(QMediaContent(QFileDialog.getOpenFileUrl()[0]))  # 选取视频文件
        self.player.play()  # 播放视频
        print(self.player.availableMetaData())
 
    def playVideo(self):
        self.player.play()
 
    def pauseVideo(self):
        self.player.pause()
 
    def videoDoubleClicked(self, text):
 
        if self.player.duration() > 0:  # 开始播放后才允许进行全屏操作
            if self.videoFullScreen:
                self.player.setVideoOutput(self.wgt_video)
                self.videoFullScreenWidget.hide()
                self.videoFullScreen = False
            else:
                self.videoFullScreenWidget.show()
                self.player.setVideoOutput(self.videoFullScreenWidget)
                self.videoFullScreenWidget.setFullScreen(1)
                self.videoFullScreen = True
 
 
if __name__ == '__main__':
    app = QApplication(sys.argv)
    vieo_gui = myMainWindow()
    vieo_gui.show()
    sys.exit(app.exec_())
    

运行效果:

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

学习&实践爱好者

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值