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

同时我们也导入自己制作的UI界面。
ui_savemain正是上一节中我们保存的py文件的名字。
那么怎么调用出来呢。

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,然后实例化这个类,直接运行我们就能看到窗体了,同时能看到我们自己放的两个按钮。
我这里是后期效果了,前期效果没有存图。先放着吧。

窗体

首先让我们来想想如何实现导入字符串的效果,把字符串输入进去很容易,但是如何把字符串正确处理并且显示图片呢?这就是整个程序第一个核心难点。
虽然鼓励大家独立思考,但是我这里直接说吧。
首先我们知道楼层信息字符串包含很多$$$$$$,那么我们首先要处理掉$,然后每个数字对应一个图块,那么我们只要建立121个(11*11)按钮,把数字放进按钮里面,显示出来,然后点击按钮,可以更改数字,然后修改完了最后再输出按钮上的数字,然后再把分隔符$填充回去就可以了。

但是按钮实在是太丑了,我们有别的东西可以利用吗,可以,就是label,这个控件没有边框,可以显示图片,让我们的界面美观起来,但是label有个重大的缺陷:它本身不能被单击事件响应——或者说当初GUI控件的作者就没设计这个功能,我们曲线救国,让label能够响应单击事件:
这里的代码不要求大家理解,简单说一下就是自定义label的信号槽,让他响应单击事件。

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)#绑定一个指定函数,这个是后面要做的功能,先放进来

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

这样label也准备好了,让我们开始编写逻辑代码。
仔细想一下,程序是不是应该先把121个label放置到窗口里,然后再绘制地图呢?
确实应该是这样,那么首先我们要确定label的坐标,足足有121个,让我们借助range函数和for循环来计算出每个label的坐标。
定位到主类,新建一个函数calculate_xy

    def calculate_xy(self):
        xy_offset = 52  # 定义偏移量,因为label的坐标并不是从(0,0)开始的
        self.xy_list = []#用来存放坐标值
        for i1 in range(11):#循环11次
            for i2 in range(11):#循环11次
                y = i1 * 32#每次循环x和y都将*32
                x = i2 * 32#因为每个label的大小是32*32,为了不重叠,每次要偏移32个像素
                xy = (x + xy_offset, y + xy_offset)#把之前的偏移量加上
                self.xy_list.append(xy)#把坐标结果放到list里面

计算好之后,就应该创建label了,新建一个函数:

    def setup_label(self):
        self.label_list = []  # 用于存放label控件方便查找
        for index in range(121):  # 循环121次
            object_name = "label_" + str(index)  # 设定label的objectName方便我们后期查找
            map_label = MyQLabel(self)  # 实例化Label类,记得用之前继承过的类
            map_label.setObjectName(object_name)  # 设定objectname
            map_label.resize(32, 32)  # 设定label大小
            x = self.xy_list[index][0]
            y = self.xy_list[index][1]
            map_label.move(x, y)  # 设定坐标
            self.label_list.append(map_label)  # 把label放进去

定位到我们的主类,在里面新建一个函数draw_map

    def draw_map(self, floor_str: str): # 传一个参数进去,用于接受楼层信息字符串
        split_floor = floor_str.split("$")  # 处理掉分隔符,取出数字做成list
        split_floor = split_floor[0:121]  # 因为会有一个空元素,对list进行切片,去掉最后一个元素,其实直接删除也可以
        for index, text in enumerate(split_floor):  # 进行迭代,enumerate函数会给每个list元素编号
            label_widget = self.label_list[index]  # 先取到对应编号的label
            image_path = os.path.join("images", text + ".png")  # 提前准备好了对应数字的图片文件
            if os.path.exists(image_path):  # 如果图片存在
                label_widget.setPixmap(QPixmap(image_path))  # 给label填充图片
            else:
                label_widget.setPixmap(
                    QPixmap("images/missing.png")
                )  # 填充一个miss图片进去来提醒我们这个数字图块没有图片
            label_widget.setToolTip(text)  # 同时设置鼠标悬浮时候的提示框文本
            # 把数字放到tooltip里面方便后期存取
            # text变量是每个图块的数字

这样我们绘图部分就处理好了。这样的话下一章我们来搞定输入和输出。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容