史上最強之《Pyqt》寫遊戲

目錄

項目展示

前言

項目來源

最後代碼

整體思路

結論


項目展示

史上最強之Pyqt寫遊戲

前言

潛水了大約半個月,這半個月實在抽不出時間來寫一下博客,因爲最近確實有點忙,不僅在練習微信小程序,有空還接了一下一些人的程序設計,雖然很多都是小打小鬧,但是也給了我很多的樂趣,說到底的還真是面相¥編程,有了目標驅動,動力就足,幹啥啥都有勁,以至於現在停下來感覺都快半身不遂了。編程快雖樂,還是要謹慎而行啊!

接下來這幾天有空的話我分享一下這幾個星期的積累,也算是經驗分享,比如下面上線的這個微信小程序,用python做後臺以及前端用vant做框架,還有一些小遊戲,小系統,總的來說每一個都可以是一個簡單的課程或者畢業小設計。

項目來源

好了,閒話不多聊,下面迴歸正題。以前用python做GUI的時候,總是使用tkinter,因爲感覺它比較簡單方便,有興趣的同學可以去我的python小項目欄目下看看,裏面以前的項目基本都是tkinter做的,在這過程中也偶爾聽說pyqt比tkinter好玩多了,但是當時並未在意,想着框架不在多,自己用着好就是好。但是好奇心驅使,最近接了個小設計,一個類似小遊戲的東西,大概意思就是兩個人分別點擊兩張圖片,如果圖片相同,則該玩家加一分,繼續翻,如果不相同,則換下一個玩家。

一開始沒有什麼思路,想着遊戲應該用pygame來做,但是鄙人對pygame不熟悉,所以放棄了,後面腦子想了一下用tkinter來做行不行,試了下太複雜了,又pass,最後想到還有個pyqt沒玩過,爲什麼不試試呢?二話不想開始裝庫,這過程就不贅述了,CSDN上有一堆教程,還有界面設計designer的使用,也不多贅述,網上有教程,我放出來給大家了,由於一開始我參考的那兩篇博客不知道是哪個了,我這邊就說一下我踩的坑。

  1. 由於pyqt有點大,所以我們換成國內源安裝,我當時用的是豆瓣,嗖嗖嗖的就下完了
    pip install PyQt5 -i https://pypi.doubanio.com/simple
    pip install pyqt5-tools -i https://pypi.doubanio.com/simple
  2. 後面這個就是designer的安裝,安裝好後在你安裝的包的路徑就能找到,我用的是瓦坎達,庫一般安裝在Anaconda3\Lib\site-packages下,然後找到pyqt5-tools文件夾,進去就能找到designer了,沒有就用搜索搜一下designer.exe
    pip install pyqt5-tools -i https://pypi.doubanio.com/simple
  3. 打開後就是這樣的界面,當然你們的應該是創建界面,我這個是我這個項目已經設計好的頁面,至於爲啥我的是中文,網上也有教程,不贅述,找百度。(說句悄悄話,英語太差,沒辦法。不過pyqt確實比tkinter好用,能拖拉設計。。。。)

  4. 設計完後找到你的.ui文件導出成py文件,命令就是下面這行,注意要進入到存放ui文件的目錄,或者你直接加個絕對路徑。

  5. pyuic5 -o name.py name.ui

     

最後代碼

# %%writefile game.py
from PyQt5.QtWidgets import QApplication, QMainWindow,QGridLayout
from PyQt5 import QtCore, QtGui, QtWidgets, QtMultimedia
from PyQt5.QtCore import QUrl, Qt
import sys
import os,random,win32api,win32con
global a
a=[]
for root, dirs, files in os.walk('./img'):   
        a=files*2 #當前路徑下所有非目錄子文件
global b
b=''
global d
d=["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]
global count,play_1,play_2
count=0
play_1=0
play_2=0
class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(1047, 813)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        
        self.pushButton_1 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_1.setGeometry(QtCore.QRect(20, 10, 191, 161))
        self.pushButton_1.setObjectName("pushButton")
        self.pushButton_1.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_1.clicked.connect(lambda:self.setimg("1"))

        self.pushButton_2 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_2.setGeometry(QtCore.QRect(830, 10, 191, 161))
        self.pushButton_2.setObjectName("pushButton_2")
        self.pushButton_2.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_2.clicked.connect(lambda:self.setimg("2"))
        
        self.pushButton_3 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_3.setGeometry(QtCore.QRect(570, 10, 191, 161))
        self.pushButton_3.setObjectName("pushButton_3")
        self.pushButton_3.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_3.clicked.connect(lambda:self.setimg("3"))
        
        self.pushButton_4 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_4.setGeometry(QtCore.QRect(290, 10, 191, 161))
        self.pushButton_4.setObjectName("pushButton_4")
        self.pushButton_4.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_4.clicked.connect(lambda:self.setimg("4"))
        
        self.pushButton_5 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_5.setGeometry(QtCore.QRect(20, 190, 191, 161))
        self.pushButton_5.setObjectName("pushButton_5")
        self.pushButton_5.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_5.clicked.connect(lambda:self.setimg("5"))
        
        self.pushButton_6 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_6.setGeometry(QtCore.QRect(830, 190, 191, 161))
        self.pushButton_6.setObjectName("pushButton_6")
        self.pushButton_6.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_6.clicked.connect(lambda:self.setimg("6"))
        
        self.pushButton_7 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_7.setGeometry(QtCore.QRect(570, 190, 191, 161))
        self.pushButton_7.setObjectName("pushButton_7")
        self.pushButton_7.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_7.clicked.connect(lambda:self.setimg("7"))
        
        self.pushButton_8 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_8.setGeometry(QtCore.QRect(290, 190, 191, 161))
        self.pushButton_8.setObjectName("pushButton_8")
        self.pushButton_8.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_8.clicked.connect(lambda:self.setimg("8"))
        
        self.pushButton_9 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_9.setGeometry(QtCore.QRect(20, 370, 191, 161))
        self.pushButton_9.setObjectName("pushButton_9")
        self.pushButton_9.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_9.clicked.connect(lambda:self.setimg("9"))
        
        self.pushButton_10 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_10.setGeometry(QtCore.QRect(830, 370, 191, 161))
        self.pushButton_10.setObjectName("pushButton_10")
        self.pushButton_10.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_10.clicked.connect(lambda:self.setimg("10"))
        
        self.pushButton_11 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_11.setGeometry(QtCore.QRect(570, 370, 191, 161))
        self.pushButton_11.setObjectName("pushButton_11")
        self.pushButton_11.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_11.clicked.connect(lambda:self.setimg("11"))
        
        self.pushButton_12 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_12.setGeometry(QtCore.QRect(290, 370, 191, 161))
        self.pushButton_12.setObjectName("pushButton_12")
        self.pushButton_12.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_12.clicked.connect(lambda:self.setimg("12"))
        
        self.pushButton_13 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_13.setGeometry(QtCore.QRect(20, 560, 191, 161))
        self.pushButton_13.setObjectName("pushButton_13")
        self.pushButton_13.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_13.clicked.connect(lambda:self.setimg("13"))
        
        self.pushButton_14 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_14.setGeometry(QtCore.QRect(830, 560, 191, 161))
        self.pushButton_14.setObjectName("pushButton_14")
        self.pushButton_14.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_14.clicked.connect(lambda:self.setimg("14"))
        
        self.pushButton_15 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_15.setGeometry(QtCore.QRect(570, 560, 191, 161))
        self.pushButton_15.setObjectName("pushButton_15")
        self.pushButton_15.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_15.clicked.connect(lambda:self.setimg("15"))
        
        self.pushButton_16 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_16.setGeometry(QtCore.QRect(290, 560, 191, 161))
        self.pushButton_16.setObjectName("pushButton_16")
        self.pushButton_16.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")
        self.pushButton_16.clicked.connect(lambda:self.setimg("16"))
        
        self.pushButton_17 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_17.setGeometry(QtCore.QRect(600, 750, 101, 41))
        self.pushButton_17.setObjectName("pushButton_17")
        self.pushButton_17.clicked.connect(self.stop)
        
        self.pushButton_18 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_18.setGeometry(QtCore.QRect(470, 750, 101, 41))
        self.pushButton_18.setObjectName("pushButton_18")
        self.pushButton_18.clicked.connect(self.pause)
        
        self.pushButton_19 = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_19.setGeometry(QtCore.QRect(350, 750, 101, 41))
        self.pushButton_19.setObjectName("pushButton_19")
        self.pushButton_19.clicked.connect(self.play)
        
        url = QUrl.fromLocalFile(r"1.mp3")
        content = QtMultimedia.QMediaContent(url)
        self.player = QtMultimedia.QMediaPlayer()
        self.player.setMedia(content)
        
        MainWindow.setCentralWidget(self.centralwidget)
        self.retranslateUi(MainWindow)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)
        
    
    def stop(self):
        self.player.stop()
        
    def play(self):
        self.player.play()
        
    def pause(self):
        self.player.pause()
        
    
    def setimg(self,name):
        global a,b,d,count,play_1,play_2
        if a==[]:
            win32api.MessageBox(0,'遊戲結束啦!\n玩家一得分:%s,玩家二得分:%s'%(play_1,play_2),"提醒",win32con.MB_ICONWARNING)
        else:
            if name in d:
                count+=1
                d.remove(name)
                buttonname="self.pushButton_%s"%name
                buttonname=eval(buttonname)
                if b=='':
                    b=random.choice(a)
                    a.remove(b)
                    buttonname.setStyleSheet("QPushButton{border-image: url(img/%s)}"%b)
                else:
                    c=random.choice(a)
                    a.remove(c)
                    buttonname.setStyleSheet("QPushButton{border-image: url(img/%s)}"%c)
                    if c==b:
                        if str(count) in ["2","6","10","14"]:
                            play_1+=1
                            win32api.MessageBox(0, "恭喜你選對了!可以繼續遊戲。\n當前玩家一得分:%s,玩家二得分:%s"%(play_1,play_2), "提醒",win32con.MB_OK)
                            b=''
                        else:
                            play_2+=1
                            win32api.MessageBox(0, "恭喜你選對了!可以繼續遊戲。\n當前玩家一得分:%s,玩家二得分:%s"%(play_1,play_2), "提醒",win32con.MB_OK)
                            b=''
                    else:
                        win32api.MessageBox(0,'很遺憾你沒選對!下一位玩家', "提醒",win32con.MB_ICONWARNING)
                        b=''
            else:
                win32api.MessageBox(0,'你已經點過該圖了!', "提醒",win32con.MB_ICONWARNING)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "點圖大戰"))
        self.player.play()
        self.pushButton_17.setText(_translate("MainWindow", "停止播放音樂"))
        self.pushButton_18.setText(_translate("MainWindow", "暫停播放音樂"))
        self.pushButton_19.setText(_translate("MainWindow", "繼續播放音樂"))

if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())
    

class Ui_MainWindow這個類就是你導出成py文件後他自動給你生成的, 我們需要下面這個調用它,俗稱搞對象。

if __name__ == '__main__':
    app = QApplication(sys.argv)
    MainWindow = QMainWindow()
    ui = Ui_MainWindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_())

 不出意外的話你就會得到下面這樣的情況,沒錯,這就是你的對象,只有軀體,沒有靈魂的!而我們真正要做的就是給他加上靈魂。

首先給按鈕穿上衣服----》》self.pushButton_1.setStyleSheet("QPushButton{border-image: url(mr/1.jpg)}")

然後給每個按鈕綁定一個事件----》》self.pushButton_1.clicked.connect(lambda:self.setimg("1"))

最後加個背景音樂,完事。

url = QUrl.fromLocalFile(r"1.mp3")
content = QtMultimedia.QMediaContent(url)
self.player = QtMultimedia.QMediaPlayer()
self.player.setMedia(content)

 需要注意的是,起初我是想每個按鈕綁定一個事件,後面發現太複雜,就想到全部按鈕綁定到同一個事件,每次點擊按鈕時傳入該按鈕的編號,然後再將字符轉換爲變量---》》buttonname="self.pushButton_%s"%name  buttonname=eval(buttonname),用來更換不同的背景圖片,也就是給你的對象換衣服。

def setimg(self,name):
        global a,b,d,count,play_1,play_2
        if a==[]:
            win32api.MessageBox(0,'遊戲結束啦!\n玩家一得分:%s,玩家二得分:%s'%(play_1,play_2),"提醒",win32con.MB_ICONWARNING)
        else:
            if name in d:
                count+=1
                d.remove(name)
                buttonname="self.pushButton_%s"%name
                buttonname=eval(buttonname)
                if b=='':
                    b=random.choice(a)
                    a.remove(b)
                    buttonname.setStyleSheet("QPushButton{border-image: url(img/%s)}"%b)
                else:
                    c=random.choice(a)
                    a.remove(c)
                    buttonname.setStyleSheet("QPushButton{border-image: url(img/%s)}"%c)
                    if c==b:
                        if str(count) in ["2","6","10","14"]:
                            play_1+=1
                            win32api.MessageBox(0, "恭喜你選對了!可以繼續遊戲。\n當前玩家一得分:%s,玩家二得分:%s"%(play_1,play_2), "提醒",win32con.MB_OK)
                            b=''
                        else:
                            play_2+=1
                            win32api.MessageBox(0, "恭喜你選對了!可以繼續遊戲。\n當前玩家一得分:%s,玩家二得分:%s"%(play_1,play_2), "提醒",win32con.MB_OK)
                            b=''
                    else:
                        win32api.MessageBox(0,'很遺憾你沒選對!下一位玩家', "提醒",win32con.MB_ICONWARNING)
                        b=''
            else:
                win32api.MessageBox(0,'你已經點過該圖了!', "提醒",win32con.MB_ICONWARNING)

整體思路

  1. 設計好界面
  2. 給到一個默認按鈕樣式
  3. 創建文件夾保存更換按鈕的8張圖片(16個按鈕,我們需要8張圖,兩兩相同),創建圖片列表,並將它*2,變成16個圖片名元素
    global a
    a=[]
    for root, dirs, files in os.walk('./img'):   
            a=files*2 #當前路徑下所有非目錄子文件
    

     

  4. 隨機選擇列表內的一個元素賦值給b,然後圖片b給到當前按鈕,從圖片列表刪除b元素,因爲一開始b是空的,當第二次點擊的時候我們判斷當前隨機獲取到的元素是否與b相同,不同則換人,同就繼續,該玩家積分加一

    global b
    b=''
    global d
    d=["1","2","3","4","5","6","7","8","9","10","11","12","13","14","15","16"]
    global count,play_1,play_2
    count=0
    play_1=0
    play_2=0
  5. 按鈕列表,每點擊一次移除一個,如果按鈕列表內沒有該按鈕,說明該按鈕已經點過了,給出提示。

結論

項目雖小,但是一開始並沒有思路,當邏輯弄清楚後,我們再轉爲代碼就容易多了,所以我們在做東西的時候應該先腦子裏有個整體思路,不然會白白浪費大把時間,寫出的東西還一團糟。

其實該代碼還能再簡化一下,每個按鈕都是類似的,我們可以循環生成,但是要將x,y搞清楚怎麼分佈的,這樣我們就能生成32個或者64個或者更多按鈕,就不限於16個了,至於按鈕排布規律留給你們去想了,小白撰寫不易,嘴下留情,點個贊吧!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章