2.1編寫編輯器邏輯代碼

VS Code打開我們的工程文件夾:
新建一個文件:editor.py
首先既然要用到GUI,自然是要import包進來:

import sys
import os
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *

from ui_savemain import Ui_MainWindow

同時我們也導(dǎo)入自己制作的UI界面。
ui_savemain正是上一節(jié)中我們保存的py文件的名字。
那么怎么調(diào)用出來呢。

class SaveEditor(QMainWindow, Ui_MainWindow):
    def __init__(self):
        super().__init__()
        self.setupUi(self)

if __name__ == "__main__":
    app = QApplication(sys.argv)
    main_window = SaveEditor()
    main_window.show()
    app.exec()

新建一個類,多重繼承QMainWindow,Ui_MainWindow,然后實例化這個類,直接運行我們就能看到窗體了,同時能看到我們自己放的兩個按鈕。
我這里是后期效果了,前期效果沒有存圖。先放著吧。

窗體

首先讓我們來想想如何實現(xiàn)導(dǎo)入字符串的效果,把字符串輸入進去很容易,但是如何把字符串正確處理并且顯示圖片呢?這就是整個程序第一個核心難點。
雖然鼓勵大家獨立思考,但是我這里直接說吧。
首先我們知道樓層信息字符串包含很多$$$$$$,那么我們首先要處理掉$,然后每個數(shù)字對應(yīng)一個圖塊,那么我們只要建立121個(11*11)按鈕,把數(shù)字放進按鈕里面,顯示出來,然后點擊按鈕,可以更改數(shù)字,然后修改完了最后再輸出按鈕上的數(shù)字,然后再把分隔符$填充回去就可以了。

但是按鈕實在是太丑了,我們有別的東西可以利用嗎,可以,就是label,這個控件沒有邊框,可以顯示圖片,讓我們的界面美觀起來,但是label有個重大的缺陷:它本身不能被單擊事件響應(yīng)——或者說當(dāng)初GUI控件的作者就沒設(shè)計這個功能,我們曲線救國,讓label能夠響應(yīng)單擊事件:
這里的代碼不要求大家理解,簡單說一下就是自定義label的信號槽,讓他響應(yīng)單擊事件。

class MyQLabel(QLabel):
    button_clicked_signal = Signal()

    def __init__(self, parent=None):
        super(MyQLabel, self).__init__(parent)
        self.button_clicked_signal.connect(self.change_map)#綁定一個指定函數(shù),這個是后面要做的功能,先放進來

    def mouseReleaseEvent(self, QMouseEvent):
        self.button_clicked_signal.emit()

這樣label也準(zhǔn)備好了,讓我們開始編寫邏輯代碼。
仔細想一下,程序是不是應(yīng)該先把121個label放置到窗口里,然后再繪制地圖呢?
確實應(yīng)該是這樣,那么首先我們要確定label的坐標(biāo),足足有121個,讓我們借助range函數(shù)和for循環(huán)來計算出每個label的坐標(biāo)。
定位到主類,新建一個函數(shù)calculate_xy

    def calculate_xy(self):
        xy_offset = 52  # 定義偏移量,因為label的坐標(biāo)并不是從(0,0)開始的
        self.xy_list = []#用來存放坐標(biāo)值
        for i1 in range(11):#循環(huán)11次
            for i2 in range(11):#循環(huán)11次
                y = i1 * 32#每次循環(huán)x和y都將*32
                x = i2 * 32#因為每個label的大小是32*32,為了不重疊,每次要偏移32個像素
                xy = (x + xy_offset, y + xy_offset)#把之前的偏移量加上
                self.xy_list.append(xy)#把坐標(biāo)結(jié)果放到list里面

計算好之后,就應(yīng)該創(chuàng)建label了,新建一個函數(shù):

    def setup_label(self):
        self.label_list = []  # 用于存放label控件方便查找
        for index in range(121):  # 循環(huán)121次
            object_name = "label_" + str(index)  # 設(shè)定label的objectName方便我們后期查找
            map_label = MyQLabel(self)  # 實例化Label類,記得用之前繼承過的類
            map_label.setObjectName(object_name)  # 設(shè)定objectname
            map_label.resize(32, 32)  # 設(shè)定label大小
            x = self.xy_list[index][0]
            y = self.xy_list[index][1]
            map_label.move(x, y)  # 設(shè)定坐標(biāo)
            self.label_list.append(map_label)  # 把label放進去

定位到我們的主類,在里面新建一個函數(shù)draw_map

    def draw_map(self, floor_str: str): # 傳一個參數(shù)進去,用于接受樓層信息字符串
        split_floor = floor_str.split("$")  # 處理掉分隔符,取出數(shù)字做成list
        split_floor = split_floor[0:121]  # 因為會有一個空元素,對list進行切片,去掉最后一個元素,其實直接刪除也可以
        for index, text in enumerate(split_floor):  # 進行迭代,enumerate函數(shù)會給每個list元素編號
            label_widget = self.label_list[index]  # 先取到對應(yīng)編號的label
            image_path = os.path.join("images", text + ".png")  # 提前準(zhǔn)備好了對應(yīng)數(shù)字的圖片文件
            if os.path.exists(image_path):  # 如果圖片存在
                label_widget.setPixmap(QPixmap(image_path))  # 給label填充圖片
            else:
                label_widget.setPixmap(
                    QPixmap("images/missing.png")
                )  # 填充一個miss圖片進去來提醒我們這個數(shù)字圖塊沒有圖片
            label_widget.setToolTip(text)  # 同時設(shè)置鼠標(biāo)懸浮時候的提示框文本
            # 把數(shù)字放到tooltip里面方便后期存取
            # text變量是每個圖塊的數(shù)字

這樣我們繪圖部分就處理好了。這樣的話下一章我們來搞定輸入和輸出。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容