PyQt挖地雷游戏学习笔记(4)

又遇到一个有意思的问题,它提醒了查阅文档和相关源码,与测试的重要性。

直接上代码,setup.py

"""
module: setup
"""
from lib import *
from config import *

form, base = loadUiType("setup.ui")
class SetupDlg(QDialog, form):
    def __init__(self):
        super(SetupDlg, self).__init__()
        self.setupUi(self)
        self.sbW.setValue(conf.w)
        self.sbH.setValue(conf.h)
        self.sbMines.setValue(conf.mines)

    def accept(self):

        conf.w = self.sbW.value()
        conf.h = self.sbH.value()
        conf.mines = self.sbMines.value()
        conf.save()
        super(SetupDlg, self).accept()

    @pyqtSlot()
    def on_pbSmall_clicked(self):
        self.sbW.setValue(10)
        self.sbH.setValue(10)
        self.sbMines.setValue(10)

    @pyqtSlot()
    def on_pbMiddle_clicked(self):
        self.sbW.setValue(16)
        self.sbH.setValue(16)
        self.sbMines.setValue(40)

    @pyqtSlot()
    def on_pbBig_clicked(self):
        self.sbW.setValue(30)
        self.sbH.setValue(16)
        self.sbMines.setValue(80)

def getSetup():
    if SetupDlg().exec_() != QDialog.Accepted: return
    return (conf.w, conf.h), conf.mines

让我困惑的是以下2个问题:

函数accept()怎么回事?它没有@pyqtSlot()修饰,不像槽函数。

QDialog.Accepted 从何而来?

首先,请教《Qt助手》。它说:

void QDialog::accept () [virtual slot]

accept()的任务是关闭模态对话框,设定返回值Accepted。

它还说,模态对话框最常用的打开办法,是调用它的exec()函数。它会返回很有用的数值。

通常,把默认的按钮如OK,与槽accept()关联;按钮Cancel与reject()关联。

接着,再看相关代码的验证。

首先,用《Qt设计师》打开setup.ui,

看到buttonBox(对话框默认按钮)中,选中的是OK和Cancel。

从“信号/槽编辑器”中看到buttonBox发出的信号,accepted()和rejected(),

与相对应的槽,accept()和reject()。

再用普通文本编辑器,打开setup.py,也会看到类似的文字内容。

事情进行至此,好像全部问题都解决了。其实不然。

还有个要紧的问题:accept()为何调用super(SetupDlg, self).accept()

这一调用是否多余?要弄明白它,最好的办法是做实验、检测。

用注释屏蔽掉 super(SetupDlg, self).accept(),

运行main.py,在程序菜单选:Config -> Setup,在弹出的对话框中按钮OK,

程序毫无反应,对话框并不关闭。

这证明了,必须调用QDialog.accept(),才能返回QDialog.Accepted,以正常关闭对话框。

时间: 2024-10-11 21:01:35

PyQt挖地雷游戏学习笔记(4)的相关文章

PyQt挖地雷游戏学习笔记(2)

分析多个文件组成的源代码,最好使用辅助工具. 我试过Source Navigator 和 Source Insight,感觉后者功能多些,比较好用. 一.程序的组成模块等文件 这个挖地雷游戏,主要由2种文件组成: 1.程序模块 主程序main.py:负责主窗口物件,按钮和菜单的设置.事件处理.程序初始化.结束等等. 游戏逻辑模块game_scene.py:负责游戏规则.棋盘显示.胜负裁判.记录得分等等. "导入"文件lib.py:导入一些通用的模块,其他文件只需导入lib.py. 游戏

PyQt挖地雷游戏学习笔记(7)

1.游戏规则 地雷随机埋设在"棋盘"方格里,挖到地雷为败,挖光全部无雷方格为胜. 2.游戏的空间表示 游戏发生在棋盘上,游戏的场景.规则,都体现在棋盘上. 棋盘,由"场景盘"和"逻辑盘"共同组成. "场景盘"是玩家挖雷面对的棋盘. "逻辑盘"是实现游戏规则所需的"雷区盘"."空区盘"和"提示盘". "逻辑盘"由数组表示. 棋盘.

PyQt挖地雷游戏学习笔记(6)

学习别人的作品,有一大好处,可以反观自己的不足. 自己的不足,往往是基础知识有欠缺,基本功不扎实. 今天,再补一课:星号表达式(*expression). 挖地雷程序中,有2处用到星号表达式.一是在main.py,另一处在game_scene.py. 先看第一处的情况: @pyqtSlot() def on_action_Setup_triggered(self): result = setup.getSetup() if not result: return self.scene.setMap

PyQt挖地雷游戏学习笔记(1)

想学会PyQt.按习惯做法,从分析学习编程实例着手. 从网上找了个"挖地雷"的源码,大卸八块,仔细解剖,力图学到些东西. 原程序中有bug,如:"棋盘"没有下边界线:挖出全部地雷后,程序没反应,不认定获胜. 我已将其铲掉,可以正常运行了. 程序源码可在此下载 所做修改,都在game_scene.py.共有2处: 一是在函数checkWin()中,原文是: if ((self.mine_map == self.flag_map).all() and (self.min

PyQt挖地雷游戏学习笔记(3)

这个程序使用了Python有特色的语法套路.先看第一个. main.py里的class MainWindow的函数init()中,有这样的语句: self.scene.setMap((conf.w, conf.h), conf.mines) 这里的变量conf,定义在config.py中,由以下语句引入的: from config import * 这里的conf.w和conf.h是什么呢?由此,转入config.py,一探究竟. #module: config import json DEFA

组合游戏学习笔记 [补档]

基础 满足以下条件的游戏是组合游戏: 有两人参与游戏, 轮流作出决策 无法作出决策的人失败, 然后游戏结束 游戏总能在有限次决策后结束 游戏的同一个状态不会多次到达 任意一个参与者在某一确定状态下可以作出的决策集合只与当前状态有关 定义先手必败状态为必败态, 先手必胜状态为必胜态, 则我们有 无法进行任何移动的状态是必败态. 可以移动到必败态的状态的是必胜态. 所有移动都只能得到必胜态的状态是必败态. 考虑如何判断一个游戏中, 先手是否必胜: 根据定义, 由于游戏中任意状态都不可能重复出现, 因

关于扫雷游戏学习笔记(二)

用户控件与窗体之间的传值:要实现当MineField中扫雷成功或失败,笑脸图标做出相应的改变. 1.通过构造函数传参 //MineField类中 public PictureBox smile; public MineField(PictureBox pb) { smile=pb; InitializeComponent(); } //在Form.Designer中的InitializeComponent里加入 this.mineField1 = new Mine.MineField(pictu

Unity3D学习笔记之七创建自己的游戏场景

到现在为止我们已经拥有了比较完备的Prefab,已经可以创建宏大的游戏场景,并以第一人称视角在场景中漫游了.这里给大家做个小的示范,建一个小场景大家在创建场景的时候需要自由发挥,做个尽量大的场景出来. 这一系列教程以及素材均参考自人人素材翻译组出品的翻译教程<Unity游戏引擎的基础入门视频教程>,下载链接附在第二篇学习笔记中. 我们以最初的添加了First Person Controller的PFB_Straight为整个场景的中心点来展开.我们先从Project中Prefabs文件夹拖出来

【Unity 3D】学习笔记三十五:游戏实例——摄像机切换镜头

摄像机切换镜头 在游戏中常常会切换摄像机来观察某一个游戏对象,能够说.在3D游戏开发中,摄像头的切换是不可或缺的. 这次我们学习总结下摄像机怎么切换镜头. 代码: private var Camera0: GameObject; private var Camera1: GameObject; private var Camera2: GameObject; private var Camera: GameObject; function Start() { //获取摄像机对象 Camera =