Python基础教程——贪吃蛇、连连看小游戏(完整版,附源码)

news2024/10/7 6:48:19

一、贪吃蛇

1. 案例介绍

贪吃蛇是一款经典的益智游戏,简单又耐玩。该游戏通过控制蛇头方向吃蛋,从而使得蛇变得越来越长。

通过上下左右方向键控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。

本例难度为中级,适合具有 Python 基础和 Pygame 编程知识的用户学习。

2. 设计要点

游戏是基于 PyGame 框架制作的,程序核心逻辑如下:

游戏界面分辨率是 640*480,蛇和食物都是由 1 个或多个 20*20 像素的正方形块儿(为了方便,下文用点表示 20*20 像素的正方形块儿) 组成,这样共有 32*24 个点,使用 pygame.draw.rect 来绘制每一个点;

初始化时蛇的长度是 3,食物是 1 个点,蛇初始的移动的方向是右,用一个数组代表蛇,数组的每个元素是蛇每个点的坐标,因此数组的第一个坐标是蛇尾,最后一个坐标是蛇头;游戏开始后,根据蛇的当前移动方向,将蛇运动方向的前方的那个点 append 到蛇数组的末位,再把蛇尾去掉,蛇的坐标数组就相当于往前挪了一位;如果蛇吃到了食物,即蛇头的坐标等于食物的坐标,那么在第 2 点中蛇尾就不用去掉,就产生了蛇长度增加的效果;食物被吃掉后,随机在空的位置(不能与蛇的身体重合) 再生成一个;通过 PyGame 的 event 监控按键,改变蛇的方向,例如当蛇向右时,下一次改变方向只能向上或者向下;当蛇撞上自身或墙壁,游戏结束,蛇头装上自身,那么蛇坐标数组里就有和舌头坐标重复的数据,撞上墙壁则是蛇头坐标超过了边界,都很好判断;其他细节:做了个开始的欢迎界面;食物的颜色随机生成;吃到实物的时候有声音提示等。

3. 示例效果

在这里插入图片描述

4. 示例源码

import pygame
from os import path
from sys import exit
from time import sleep
from random import choice
from itertools import product
from pygame.locals import QUIT, KEYDOWN


def direction_check(moving_direction, change_direction):
directions = [['up', 'down'], ['left', 'right']]
if moving_direction in directions[0] and change_direction in directions[1]:
return change_direction
elif moving_direction in directions[1] and change_direction in directions[0]:
return change_direction
return moving_direction


class Snake:
colors = list(product([0, 64, 128, 192, 255], repeat=3))[1:-1]    
def __init__(self):
self.map = {(x, y): 0 for x in range(32) for y in range(24)}
self.body = [[100, 100], [120, 100], [140, 100]]
self.head = [140, 100]
self.food = []
self.food_color = []
self.moving_direction = 'right'
self.speed = 4
self.generate_food()
self.game_started = False


def check_game_status(self):
if self.body.count(self.head) > 1:
return True
if self.head[0] < 0 or self.head[0] > 620 or self.head[1] < 0 or self.head[1] > 460:
return True
return False


def move_head(self):
moves = {
'right': (20, 0),
'up': (0, -20),
'down': (0, 20),
'left': (-20, 0)
}
step = moves[self.moving_direction]
self.head[0] += step[0]
self.head[1] += step[1]


def generate_food(self):
self.speed = len(
self.body) // 16 if len(self.body) // 16 > 4 else self.speed
for seg in self.body:
x, y = seg
self.map[x // 20, y // 20] = 1
empty_pos = [pos for pos in self.map.keys() if not self.map[pos]]
result = choice(empty_pos)
self.food_color = list(choice(self.colors))
self.food = [result[0] * 20, result[1] * 20]


def main():
key_direction_dict = {
119: 'up',  # W
115: 'down',  # S
97: 'left',  # A
100: 'right',  # D
273: 'up',  # UP
274: 'down',  # DOWN
276: 'left',  # LEFT
275: 'right',  # RIGHT
}


fps_clock = pygame.time.Clock()
pygame.init()
pygame.mixer.init()
snake = Snake()
sound = False
if path.exists('eat.wav'):
sound_wav = pygame.mixer.Sound("eat.wav")
sound = True
title_font = pygame.font.SysFont('simsunnsimsun', 32)
welcome_words = title_font.render(
'贪吃蛇', True, (0, 0, 0), (255, 255, 255))
tips_font = pygame.font.SysFont('simsunnsimsun', 20)
start_game_words = tips_font.render(
'点击开始', True, (0, 0, 0), (255, 255, 255))
close_game_words = tips_font.render(
'按ESC退出', True, (0, 0, 0), (255, 255, 255))
gameover_words = title_font.render(
'游戏结束', True, (205, 92, 92), (255, 255, 255))
win_words = title_font.render(
'蛇很长了,你赢了!', True, (0, 0, 205), (255, 255, 255))
screen = pygame.display.set_mode((640, 480), 0, 32)
pygame.display.set_caption('贪吃蛇')
new_direction = snake.moving_direction
while 1:
for event in pygame.event.get():
if event.type == QUIT:
exit()
elif event.type == KEYDOWN:
if event.key == 27:
exit()
if snake.game_started and event.key in key_direction_dict:
direction = key_direction_dict[event.key]
new_direction = direction_check(
snake.moving_direction, direction)
elif (not snake.game_started) and event.type == pygame.MOUSEBUTTONDOWN:
x, y = pygame.mouse.get_pos()
if 213 <= x <= 422 and 304 <= y <= 342:
snake.game_started = True
screen.fill((255, 255, 255))
if snake.game_started:
snake.moving_direction = new_direction  # 在这里赋值,而不是在event事件的循环中赋值,避免按键太快
snake.move_head()
snake.body.append(snake.head[:])
if snake.head == snake.food:
if sound:
sound_wav.play()
snake.generate_food()
else:
snake.body.pop(0)
for seg in snake.body:
pygame.draw.rect(screen, [0, 0, 0], [
seg[0], seg[1], 20, 20], 0)
pygame.draw.rect(screen, snake.food_color, [
snake.food[0], snake.food[1], 20, 20], 0)
if snake.check_game_status():
screen.blit(gameover_words, (241, 310))
pygame.display.update()
snake = Snake()
new_direction = snake.moving_direction
sleep(3)
elif len(snake.body) == 512:
screen.blit(win_words, (33, 210))
pygame.display.update()
snake = Snake()
new_direction = snake.moving_direction
sleep(3)
else:
screen.blit(welcome_words, (240, 150))
screen.blit(start_game_words, (246, 310))
screen.blit(close_game_words, (246, 350))
pygame.display.update()
fps_clock.tick(snake.speed)

if __name__ == '__main__':
main()

____________________________________________________________________________________________________________

二、连连看

1. 案例介绍

连连看是一款曾经非常流行的小游戏。游戏规则:

  1. 点击选中两个相同的方块。

  2. 两个选中的方块之间连接线的折点不超过两个(接线由X轴和Y轴的平行线组成)。

  3. 每找出一对,它们就会自动消失。

  4. 连线不能从尚未消失的图案上经过。

  5. 把所有的图案全部消除即可获得胜利。

2. 设计思路

  1. 生成成对的图片元素。

  2. 将图片元素打乱排布。

  3. 定义什么才算 相连(两张图片的连线不多于3跟直线,或者说转角不超过2个)。

  4. 实现 相连 判断算法。

  5. 消除图片元素并判断是否消除完毕。

3. 示例效果

4. 示例源码

from tkinter import *
from tkinter.messagebox import *
from threading import Timer
import time
import random


class Point:
# 点类
def __init__(self, x, y):
self.x = x
self.y = y


# --------------------------------------
'''
判断选中的两个方块是否可以消除
'''


def IsLink(p1, p2):
if lineCheck(p1, p2):
return True
if OneCornerLink(p1, p2):  # 一个转弯(折点)的联通方式
return True
if TwoCornerLink(p1, p2):  # 两个转弯(折点)的联通方式
return True
return False

# ---------------------------
def IsSame(p1, p2):
if map[p1.x][p1.y] == map[p2.x][p2.y]:
print("clicked at IsSame")
return True
return False
def callback(event):  # 鼠标左键事件代码
global Select_first, p1, p2
global firstSelectRectId, SecondSelectRectId


# print ("clicked at", event.x, event.y,turn)
x = (event.x) // 40  # 换算棋盘坐标
y = (event.y) // 40
print("clicked at", x, y)


if map[x][y] == " ":
showinfo(title="提示", message="此处无方块")
else:
if Select_first == False:
p1 = Point(x, y)
# 画选定(x1,y1)处的框线
firstSelectRectId = cv.create_rectangle(x * 40, y * 40, x * 40 + 40, y * 40 + 40, width=2, outline="blue")
Select_first = True
else:
p2 = Point(x, y)
# 判断第二次点击的方块是否已被第一次点击选取,如果是则返回。
if (p1.x == p2.x) and (p1.y == p2.y):
return
# 画选定(x2,y2)处的框线
print('第二次点击的方块', x, y)
#SecondSelectRectId=cv.create_rectangle(100,20,x*40+40,y*40+40,width=2,outline="yellow")
SecondSelectRectId = cv.create_rectangle(x * 40, y * 40, x * 40 + 40, y * 40 + 40, width=2,
outline="yellow")
print('第二次点击的方块', SecondSelectRectId)
cv.pack()


# 判断是否连通
if IsSame(p1, p2) and IsLink(p1, p2):
print('连通', x, y)
Select_first = False
# 画选中方块之间连接线
drawLinkLine(p1, p2)
# clearTwoBlock()
# time.sleep(0.6)
# clearFlag=True
t = Timer(timer_interval, delayrun)  # 定时函数
t.start()


else:  # 重新选定第一个方块
# 清除第一个选定框线
cv.delete(firstSelectRectId)
cv.delete(SecondSelectRectId)
# print('清除第一个选定框线')
# firstSelectRectId=SecondSelectRectId
# p1=Point(x,y)           #设置重新选定第一个方块的坐标
Select_first = False


timer_interval = 0.3  # 0.3秒


# --------------------------------------
def delayrun():
clearTwoBlock()  # 清除连线及方块


def clearTwoBlock():  # 清除连线及方块
# 延时0.1秒
# time.sleep(0.1)
# 清除第一个选定框线
cv.delete(firstSelectRectId)
# 清除第2个选定框线
cv.delete(SecondSelectRectId)
# 清空记录方块的值
map[p1.x][p1.y] = " "
cv.delete(image_map[p1.x][p1.y])
map[p2.x][p2.y] = " "
cv.delete(image_map[p2.x][p2.y])
Select_first = False
undrawConnectLine()  # 清除选中方块之间连接线


def drawQiPan():  # 画棋盘
for i in range(0, 15):
cv.create_line(20, 20 + 40 * i, 580, 20 + 40 * i, width=2)
for i in range(0, 15):
cv.create_line(20 + 40 * i, 20, 20 + 40 * i, 580, width=2)
cv.pack()
def print_map():  # 输出map地图
global image_map
for x in range(0, Width):  # 0--14
for y in range(0, Height):  # 0--14
if (map[x][y] != ' '):
img1 = imgs[int(map[x][y])]
id = cv.create_image((x * 40 + 20, y * 40 + 20), image=img1)
image_map[x][y] = id
cv.pack()
for y in range(0, Height):  # 0--14
for x in range(0, Width):  # 0--14
print(map[x][y], end=' ')
print(",", y)


'''
* 同行同列情况消除方法 原理:如果两个相同的被消除元素之间
的空格数spaceCount等于他们的(行/列差-1)则 两者可以联通消除
* x代表列,y代表行
* param p1 第一个保存上次选中点坐标的点对象
* param p2 第二个保存上次选中点坐标的点对象

'''
# 直接连通
def lineCheck(p1, p2):
absDistance = 0
spaceCount = 0
if (p1.x == p2.x or p1.y == p2.y):  # 同行同列的情况吗?
print("同行同列的情况------")
# 同列的情况
if (p1.x == p2.x and p1.y != p2.y):
print("同列的情况")
# 绝对距离(中间隔着的空格数)
absDistance = abs(p1.y - p2.y) - 1
# 正负值
if p1.y - p2.y > 0:
zf = -1
else:
zf = 1
for i in range(1, absDistance + 1):
if (map[p1.x][p1.y + i * zf] == " "):
# 空格数加1
spaceCount += 1
else:
break;  # 遇到阻碍就不用再探测了
# 同行的情况
elif (p1.y == p2.y and p1.x != p2.x):
print(" 同行的情况")
absDistance = abs(p1.x - p2.x) - 1
# 正负值
if p1.x - p2.x > 0:
zf = -1
else:
zf = 1
for i in range(1, absDistance + 1):
if (map[p1.x + i * zf][p1.y] == " "):
# 空格数加1
spaceCount += 1
else:
break;  # 遇到阻碍就不用再探测了
if (spaceCount == absDistance):
# 可联通
print(absDistance, spaceCount)
print("行/列可直接联通")
return True
else:
print("行/列不能消除!")
return False
else:
# 不是同行同列的情况所以直接返回false
return False;
# --------------------------------------


# 第二种,直角连通
'''
直角连接,即X,Y坐标都不同的,可以用这个方法尝试连接
param first:选中的第一个点
param second:选中的第二个点
'''


def OneCornerLink(p1, p2):
# 第一个直角检查点,如果这里为空则赋予相同值供检查
checkP = Point(p1.x, p2.y)
# 第二个直角检查点,如果这里为空则赋予相同值供检查
checkP2 = Point(p2.x, p1.y);
# 第一个直角点检测
if (map[checkP.x][checkP.y] == " "):
if (lineCheck(p1, checkP) and lineCheck(checkP, p2)):
linePointStack.append(checkP)
print("直角消除ok", checkP.x, checkP.y)
return True
# 第二个直角点检测
if (map[checkP2.x][checkP2.y] == " "):
if (lineCheck(p1, checkP2) and lineCheck(checkP2, p2)):
linePointStack.append(checkP2)
print("直角消除ok", checkP2.x, checkP2.y)
return True
print("不能直角消除")
return False;


# -----------------------------------------
'''
#第三种,双直角连通
双直角联通判定可分两步走:
1. 在p1点周围4个方向寻找空格checkP
2. 调用OneCornerLink(checkP, p2)
3. 即遍历 p1 4 个方向的空格,使之成为 checkP,然后调用 OneCornerLink(checkP,p2)判定是否为真,
4. 如果为真则可以双直角连同,否则当所有的空格都遍历完而没有找
 到一个checkP使OneCornerLink(checkP, p2)为真,则两点不能连同
 具体代码:
 双直角连接方法
 @param p1 第一个点
 @param p2 第二个点
'''


def TwoCornerLink(p1, p2):
checkP = Point(p1.x, p1.y)
# 四向探测开始
for i in range(0, 4):
checkP.x = p1.x
checkP.y = p1.y
# 向下
if (i == 3):
checkP.y += 1
while ((checkP.y < Height) and map[checkP.x][checkP.y] == " "):
linePointStack.append(checkP)
if (OneCornerLink(checkP, p2)):
print("下探测OK")
return True
else:
linePointStack.pop()
checkP.y += 1
print("ssss", checkP.y, Height - 1)
# 补充两个折点都在游戏区域底侧外部
if checkP.y == Height:  # 出了底部,则仅需判断p2能否也达到底部边界
z = Point(p2.x, Height - 1)  # 底部边界点
if lineCheck(z, p2):  # 两个折点在区域外部的底侧
linePointStack.append(Point(p1.x, Height))
linePointStack.append(Point(p2.x, Height))
print("下探测到游戏区域外部OK")
return True
# 向右
elif (i == 2):
checkP.x += 1
while ((checkP.x < Width) and map[checkP.x][checkP.y] == " "):
linePointStack.append(checkP)
if (OneCornerLink(checkP, p2)):
print("右探测OK")
return True
else:
linePointStack.pop()
checkP.x += 1
# 补充两个折点都在游戏区域右侧外部
if checkP.x == Width:  # 出了右侧,则仅需判断p2能否也达到右部边界
z = Point(Width - 1, p2.y)  # 右部边界点
if lineCheck(z, p2):  # 两个折点在区域外部的底侧
linePointStack.append(Point(Width, p1.y))
linePointStack.append(Point(Width, p2.y))
print("右探测到游戏区域外部OK")
return True
# 向左
elif (i == 1):
checkP.x -= 1
while ((checkP.x >= 0) and map[checkP.x][checkP.y] == " "):
linePointStack.append(checkP)
if (OneCornerLink(checkP, p2)):
print("左探测OK")
return True
else:
linePointStack.pop()
checkP.x -= 1
# 向上
elif (i == 0):
checkP.y -= 1
while ((checkP.y >= 0) and map[checkP.x][checkP.y] == " "):
linePointStack.append(checkP)
if (OneCornerLink(checkP, p2)):
print("上探测OK")
return True
else:
linePointStack.pop()
checkP.y -= 1


# 四个方向都寻完都没找到适合的checkP点
print("两直角连接没找到适合的checkP点")
return False;


# ---------------------------
# 画连接线
def drawLinkLine(p1, p2):
if (len(linePointStack) == 0):       
Line_id.append(drawLine(p1, p2))
else:
print(linePointStack, len(linePointStack))
if (len(linePointStack) == 1):
z = linePointStack.pop()
print("一折连通点z", z.x, z.y)
Line_id.append(drawLine(p1, z))
Line_id.append(drawLine(p2, z))
if (len(linePointStack) == 2):
z1 = linePointStack.pop()
print("2折连通点z1", z1.x, z1.y)
Line_id.append(drawLine(p2, z1))
z2 = linePointStack.pop()
print("2折连通点z2", z2.x, z2.y)
Line_id.append(drawLine(z1, z2))
Line_id.append(drawLine(p1, z2))


# 删除连接线
def undrawConnectLine():
while len(Line_id) > 0:
idpop = Line_id.pop()
cv.delete(idpop)


def drawLine(p1, p2):
print("drawLine p1,p2", p1.x, p1.y, p2.x, p2.y)
# cv.create_line( 40+20, 40+20,200,200,width=5,fill='red')
id = cv.create_line(p1.x * 40 + 20, p1.y * 40 + 20, p2.x * 40 + 20, p2.y * 40 + 20, width=5, fill='red')
# cv.pack()
return id


# --------------------------------------
def create_map():  # 产生map地图
global map
# 生成随机地图
# 将所有匹配成对的动物物种放进一个临时的地图中
tmpMap = []
m = (Width) * (Height) // 10
print('m=', m)
for x in range(0, m):
for i in range(0, 10):  # 每种方块有10个
tmpMap.append(x)
random.shuffle(tmpMap)
for x in range(0, Width):  # 0--14
for y in range(0, Height):  # 0--14
map[x][y] = tmpMap[x * Height + y]


# --------------------------------------
def find2Block(event):  # 自动查找
global firstSelectRectId, SecondSelectRectId
m_nRoW = Height
m_nCol = Width
bFound = False;
# 第一个方块从地图的0位置开始
for i in range(0, m_nRoW * m_nCol):
# 找到则跳出循环
if (bFound):
break


# 算出对应的虚拟行列位置
x1 = i % m_nCol
y1 = i // m_nCol
p1 = Point(x1, y1)
# 无图案的方块跳过
if (map[x1][y1] == ' '):
continue
# 第二个方块从前一个方块的后面开始
for j in range(i + 1, m_nRoW * m_nCol):
# 算出对应的虚拟行列位置
x2 = j % m_nCol
y2 = j // m_nCol
p2 = Point(x2, y2)
# 第二个方块不为空 且与第一个方块的动物相同
if (map[x2][y2] != ' ' and IsSame(p1, p2)):
# 判断是否可以连通
if (IsLink(p1, p2)):
bFound = True
break
# 找到后自动消除
if (bFound):  # p1(x1,y1)与p2(x2,y2)连通
print('找到后', p1.x, p1.y, p2.x, p2.y)
# 画选定(x1,y1)处的框线
firstSelectRectId = cv.create_rectangle(x1 * 40, y1 * 40, x1 * 40 + 40, y1 * 40 + 40, width=2, outline="red")
# 画选定(x2,y2)处的框线
secondSelectRectId = cv.create_rectangle(x2 * 40, y2 * 40, x2 * 40 + 40, y2 * 40 + 40, width=2, outline="red")
# t=Timer(timer_interval,delayrun)#定时函数
# t.start()
return bFound


# 游戏主逻
root = Tk()
root.title("Python连连看 ")
imgs = [PhotoImage(file='images\\bar_0' + str(i) + '.gif') for i in range(0, 10)]  # 所有图标图案
Select_first = False  # 是否已经选中第一块
firstSelectRectId = -1  # 被选中第一块地图对象
SecondSelectRectId = -1  # 被选中第二块地图对象
clearFlag = False``linePointStack = []
Line_id = []
Height = 10
Width = 10
map = [[" " for y in range(Height)] for x in range(Width)]
image_map = [[" " for y in range(Height)] for x in range(Width)]
cv = Canvas(root, bg='green', width=440, height=440)
# drawQiPan( )
cv.bind("<Button-1>", callback)  # 鼠标左键事件
cv.bind("<Button-3>", find2Block)  # 鼠标右键事件
cv.pack()
create_map()  # 产生map地图
print_map()  # 打印map地图
root.mainloop()

最后这里免费分享给大家一份Python学习资料,包含视频、源码。课件,希望能帮到那些不满现状,想提升自己却又没有方向的朋友,也可以和我一起来学习交流呀。
编程资料、学习路线图、源代码、软件安装包等!【点击这里】领取!
Python所有方向的学习路线图,清楚各个方向要学什么东西
100多节Python课程视频,涵盖必备基础、爬虫和数据分析
100多个Python实战案例,学习不再是只会理论
华为出品独家Python漫画教程,手机也能学习
历年互联网企业Python面试真题,复习时非常方便

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/842312.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

pointpillars在Ubuntu2004训练的总结

1、找到pointpcdet-master之后在此打开终端输入code进入VScode界面 code 2、激活pp环境 conda activate pp 3、cd进入tools cd tools 4、将kitti数据集准备好放入data路径下之后开始训练 python train.py --cfg_file cfgs/kitti_models/pointpillar.yaml 5、训练完成之…

AOSP开发——APN配置文件路径

Android1~9&#xff0c;APN配置文件路径&#xff1a; vendor/sprd/telephony-res/apn/apns-conf_8.xml Android10~12&#xff0c;APN配置文件路径&#xff1a; /vendor/sprd/telephony-res/apn/apns-conf_8_v2.xml Android13&#xff0c;APN配置文件路径&#xff1a; /vendor/…

一文读懂快速开发平台

一、开发平台是什么&#xff1f; 开发平台是指以一或多种编程语言为基础而开发的一种软件&#xff0c;通常其不作为最终的软件产品&#xff0c;它是一类可二次开发的软件框架&#xff0c;开发者能利用其高效地开发各类软件产品。 在利用开发平台进行开发工作时&#xff0c;可摒…

基于Home Assistant远程开门

基于Home Assistant远程开门 1.购买云服务器 1.1 阿里云服务器 本人使用的是阿里云服务器&#xff0c;其他的腾讯云&#xff0c;百度云都可以 如果你想要一个建议的话&#xff1a; 推荐在打折优惠的时候买&#xff0c;比如双十一 阿里云最近有一个飞天计划&#xff0c;在校…

关于丢失安卓秘钥的撞sha-1值的办法

实验得知&#xff0c;安卓sha-1和keytool生成秘钥签名文件的时间有关。 前提条件是&#xff0c;开发者必须知道生成秘钥的所有细节参数 以下是撞文件代码&#xff08;重复生成&#xff09; import time import osidx 0while True:cmdkeytool -keyalg RSA -genkeypair -alia…

【机器学习】 贝叶斯理论的变分推理

许志永 一、说明 贝叶斯原理&#xff0c;站在概率角度上似乎容易解释&#xff0c;但站在函数立场上就不那么容易了&#xff1b;然而&#xff0c;在高端数学模型中&#xff0c;必须要在函数和集合立场上有一套完整的概念&#xff0c;其迭代和运算才能有坚定的理论基础。 二、贝叶…

Qt能跨多少个平台?Qt能支持多少个平台?

2023年8月5日&#xff0c;周日下午 目录 Qt所支持的平台更多关于Qt支持的信息 Qt所支持的平台 图中显示的平台都支持。 想要更详细的平台支持信息可以查看&#xff1a;Supported Platforms | Qt 5.15 更多关于Qt支持的信息 Qt - 支持的平台及语言

【技巧】如何保护PowerPoint不被改动?

PPT&#xff0c;也就是PowerPoint&#xff0c;是很多小伙伴在工作生活中经常用到的图形演示文稿软件。 做好PPT后&#xff0c;担心自己不小心改动了或者不想他人随意更改&#xff0c;我们可以如何保护PPT呢&#xff1f;下面小编就来分享两个常用的方法&#xff1a; 1. 将PPT改…

Bert详细学习及代码实现详解

BERT概述 BERT的全称是Bidirectional Encoder Representation from Transformers&#xff0c;即双向Transformer的Encoder&#xff0c;因为decoder是不能获要预测的信息的。在大型语料库&#xff08;Wikipedia BookCorpus&#xff09;上训练一个大型模型&#xff08;12 层到 …

windows为nginx添加定时任务(开机延迟启动)

windows开机启动任务 调用定时任务管理器选中windows创建基本任务设置名称和描述设置触发器 并且添加个延迟触发设置操作设置条件配置设置 调用定时任务管理器 winr 输入 taskschd.msc回车 选中windows创建基本任务 设置名称和描述 设置触发器 并且添加个延迟触发 设置操作 …

深入学习 Redis - 事务、实现原理、指令使用及场景

目录 一、Redis 事务 vs MySQL事务 二、Redis 事务的执行原理 2.1、执行原理 2.2、Redis 事务设计这么简单&#xff0c;为什么不涉及成 MySQL 那样强大呢&#xff1f; 三、Redis 事务的使用 3.1、使用场景 3.2、具体演示 开启/执行/放弃事务 watch 监控 watch 实现原理…

Visual ChatGPT:Microsoft ChatGPT 和 VFM 相结合

推荐&#xff1a;使用 NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 什么是Visual ChatGPT&#xff1f; Visual ChatGPT 是一个包含 Visual Foundation 模型 &#xff08;VFM&#xff09; 的系统&#xff0c;可帮助 ChatGPT 更好地理解、生成和编辑视觉信息。VFM 能够指…

UML箭头汇总

参考&#xff1a;http://www.cnblogs.com/damsoft/archive/2016/10/24/5993602.html 1.UML简介 Unified Modeling Language (UML)又称统一建模语言或标准建模语言。 简单说就是以图形方式表现模型&#xff0c;根据不同模型进行分类&#xff0c;在UML 2.0中有13种图&#xff…

Hi,运维,你懂Java吗--No.9:线程池

作为运维&#xff0c;你不一定要会写Java代码&#xff0c;但是一定要懂Java在生产跑起来之后的各种机制。 本文为《Hi&#xff0c;运维&#xff0c;你懂Java吗》系列文章 第九篇&#xff0c;敬请关注后续系列文章 欢迎关注 龙叔运维&#xff08;公众号&#xff09; 持续分享运维…

8个最高效的Python爬虫框架,你用过几个?

前言 嗨喽~大家好呀&#xff0c;这里是魔王呐 ❤ ~! 小编收集了一些较为高效的Python爬虫框架。分享给大家。 1.Scrapy Scrapy是一个为了爬取网站数据&#xff0c;提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘&#xff0c;信息处理或存储历史数据等一系列的程…

Springboot @Validated注解详细说明

在Spring Boot中&#xff0c;Validated注解用于验证请求参数。它可以应用在Controller类或方法上 1、引入依赖 <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId> </depen…

SpringBoot源码分析(7)--prepareContext/准备应用上下文

文章目录 一、前言二、prepareContext2.1、context.setEnvironment2.2、postProcessApplicationContext(context);2.3、applyInitializers(context)2.4、发布ApplicationContextInitializedEvent事件2.5、打印启动和profile日志2.6、注册单例Bean2.6.1、手工注册单例Bean流程 2…

尚品汇总结七:商品详情模块(面试专用)

一、业务介绍 订单业务在整个电商平台中处于核心位置&#xff0c;也是比较复杂的一块业务。是把“物”变为“钱”的一个中转站。 整个订单模块一共分四部分组成&#xff1a; 结算页面 在购物车列表页面中,有一个结算的按钮,用户一点击这个按钮时,跳转到结算页,结算页展示了用…

单细胞测序基础知识

构建文库 上机测序 根据不同的荧光检测不同的碱基 质量控制&#xff08;质控QC&#xff09; 去除低质量的序列 表达定量 统计reads数&#xff0c;进而得到表达矩阵 标准化 让所有样本处在同一起跑线上 主成分分析PCA 图中每个点都代表一个样本&#xff0c;不同颜色…

【Linux】网络套接字知识点补足

目录 1 地址转换函数 1.1 字符串转in_addr的函数: 1.2 in_addr转字符串的函数: 1.3 关于inet_ntoa 2 TCP协议通讯流程 1 地址转换函数 本节只介绍基于IPv4的socket网络编程,sockaddr_in中的成员struct in_addr sin_addr表示32位 的IP 地址但是我们通常用点分十进制的字符串…