witotto 2 weeks ago
parent 4058ce6c0f
commit 6b64c9641a

Binary file not shown.

After

Width:  |  Height:  |  Size: 174 KiB

@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Python 3.8" project-jdk-type="Python SDK" />
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/software.iml" filepath="$PROJECT_DIR$/.idea/software.iml" />
</modules>
</component>
</project>

@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

Binary file not shown.

Binary file not shown.

@ -0,0 +1,48 @@
import requests
def get_weather_data(token, location):
# 构建 API URL
url = f"https://api.caiyunapp.com/v2.6/{token}/{location}/weather?dailysteps=3&hourlysteps=48"
try:
# 发送 GET 请求
response = requests.get(url)
# 检查请求是否成功
response.raise_for_status()
# 解析 JSON 数据
weather_data = response.json()
return weather_data
except requests.exceptions.RequestException as e:
print(f"Error fetching data: {e}")
return None
def extract_precipitation_probability(weather_data):
# 检查天气数据是否有效
if weather_data and 'result' in weather_data and 'hourly' in weather_data['result']:
# 提取降水概率数据
precipitation_data = weather_data['result']['hourly'].get('precipitation', [])
# 返回第一个降水概率
if precipitation_data:
return precipitation_data[0].get("probability") # 返回第一个概率
else:
return None # 如果没有数据,则返回 None
else:
return None # 如果 weather_data 不符合条件,则返回 None
def interpret_precipitation_probability(probability):
if probability is not None:
probability = float(probability) # 确保是浮点数
if probability >= 50:
return "根据降水概率,预计会下雨,请携带雨具。"
elif probability > 0:
return "降水概率较低,但可能会有小雨,请留意天气。"
else:
return "预计不会下雨。"
else:
return "无法获取降水概率。"

@ -0,0 +1,159 @@
import requests
import psycopg2
import config
from interface import * # 导入界面组件
class Active_arrangement:
def __init__(self, ui):
self.ui = ui
# 连接日历组件的 clicked 信号到处理函数
self.ui.calendarWidget.clicked.connect(self.handle_date_click)
# 获取天气信息
token = "9b946754f72e513dd4d7950b67ed8ae3" # 替换为你的 API token
city_id = "120110" # 替换为你要查询的地理位置
weather_data = self.get_weather_data(token, city_id)
# 提取天气信息
weather_message = self.extract_weather_info(weather_data)
weather_message, _ = weather_message # 只提取第一个元素
# 将天气信息插入到 weatherlabel
self.ui.weatherlabel.setText(f"天气: {weather_message}")
def handle_date_click(self, date):
# 获取选中日期,并格式化为 "yyyy-MM-dd"
selected_date = self.ui.calendarWidget.selectedDate().toString("yyyy-MM-dd")
# 获取该日期的已注册活动信息
activities = self.get_registered_activities(selected_date)
self.populate_activity_table(activities)
def get_weather_data(self, token, city_id):
url = f"https://restapi.amap.com/v3/weather/weatherInfo?city={city_id}&key={token}"
response = requests.get(url)
return response.json()
def extract_weather_info(self, weather_data):
if weather_data['status'] == '1':
# 提取实况天气信息
live_info = weather_data['lives'][0] # 取第一个元素
weather_message = (
f"省份:{live_info['province']}\n"
f"城市:{live_info['city']}\n"
f"天气现象:{live_info['weather']}\n"
f"实时气温:{live_info['temperature']}°C\n"
f"风向:{live_info['winddirection']}\n"
f"风力:{live_info['windpower']}\n"
f"湿度:{live_info['humidity']}%\n"
f"数据发布时间:{live_info['reporttime']}\n"
)
# 提取预报天气信息
forecast_message = ""
if 'forecast' in weather_data:
forecast_info = weather_data['forecast']
forecast_message = "预报天气信息:\n"
for cast in forecast_info['casts']:
forecast_message += (
f"日期:{cast['date']}\n"
f"星期:{cast['week']}\n"
f"白天天气:{cast['dayweather']}\n"
f"晚上天气:{cast['nightweather']}\n"
f"白天温度:{cast['daytemp']}°C\n"
f"晚上温度:{cast['nighttemp']}°C\n"
f"白天风向:{cast['daywind']}\n"
f"晚上风向:{cast['nightwind']}\n"
f"白天风力:{cast['daypower']}\n"
f"晚上风力:{cast['nightpower']}\n\n"
)
weather_message += forecast_message
# 计算是否适合出门
suitable_for_outdoor = self.is_suitable_for_outdoor(live_info)
return weather_message, suitable_for_outdoor
return "无法获取天气信息", False # 确保返回一个有效的元组
def is_suitable_for_outdoor(self, weather_info):
temperature = int(weather_info['temperature'])
humidity = int(weather_info['humidity'])
wind_power_str = weather_info['windpower'].strip() # 去掉前后空格
wind_power = int(''.join(filter(str.isdigit, wind_power_str))) # 提取数字部分并转换为整数
# 基于温度、湿度和风力的更复杂规则判断是否适合出门
if temperature < 10:
self.show_message("温馨提示", "温度过低,不适合出门。")
return False
elif temperature > 30:
self.show_message("温馨提示", "温度过高,不适合出门。")
return False
elif humidity >= 80:
self.show_message("温馨提示", "湿度过高,可能会下雨,建议取消活动。")
return False
elif wind_power > 5: # 假设风力超过5级不适合出门
self.show_message("温馨提示", "风力过大,不适合出门。")
return False
return True
def handle_weather_adjustment(self, suitable_for_outdoor):
if not suitable_for_outdoor:
# 如果不适合出门,可以自动取消户外活动或者调整活动
self.show_message("活动调整", "当前天气不适合进行户外活动,建议调整或取消。")
# 可以进一步添加取消或重新安排的逻辑
def show_message(self, title, message):
msg_box = QtWidgets.QMessageBox()
msg_box.setWindowTitle(title)
msg_box.setText(message)
msg_box.exec_()
def populate_activity_table(self, activities):
"""
将活动信息填充到 arrangetableWidget
"""
self.ui.arrangetableWidget.setRowCount(0) # 清空现有内容
for row, activity in enumerate(activities):
self.ui.arrangetableWidget.insertRow(row)
# 插入活动信息,例如活动名称和时间
self.ui.arrangetableWidget.setItem(row, 0, QtWidgets.QTableWidgetItem(activity["activity_name"]))
# 隐藏行号
self.ui.arrangetableWidget.verticalHeader().setVisible(False)
def get_registered_activities(self, date):
"""
获取指定日期的已注册活动信息
"""
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432") as conn:
with conn.cursor() as cur:
# 使用 %s 占位符防止 SQL 注入
cur.execute("""
SELECT a.activityname, a.activitydatetime
FROM activities a
INNER JOIN registrations r ON a.activityid = r.activity_id
INNER JOIN users u ON r.user_id = u.userid
WHERE DATE(a.activitydatetime) = %s AND u.userid = %s
""", (date, config.user_now)) # 传入的是 "2024-11-20" 和特定用户的 userid
result = cur.fetchall()
# 将查询结果转换为字典列表格式
activities = [{"activity_name": row[0], "activity_time": row[1]} for row in result]
return activities if activities else [{"activity_name": "无活动信息", "activity_time": ""}]
def check_activity_conflict(self, new_activity_time, new_activity_name):
"""
检查新活动是否与已有活动时间冲突
"""
activities = self.get_registered_activities(new_activity_time)
for activity in activities:
if self.is_time_conflict(new_activity_time, activity['activity_time']):
self.show_message("活动冲突",
f"新活动 {new_activity_name} 与现有活动 {activity['activity_name']} 时间冲突。")
return True
return False

@ -0,0 +1,438 @@
import psycopg2
import sys
import interface
from interface import *
import config
from PyQt5.QtWidgets import QMessageBox, QTableWidgetItem
from PyQt5 import QtWidgets
from store import Store
class ActivityManager:
def __init__(self, ui):
self.ui = ui
self.Store = Store(self.ui)
def handle_double_click(self, row, col):
# 处理双击事件获取活动ID并执行删除操作
item = self.ui.active_table.item(row, 0) # 假设活动ID在第一列
if item is not None:
activityid_text = item.text() # 获取文本内容
try:
config.activityid = int(activityid_text) # 尝试转换为整数
except ValueError:
print("活动ID无效无法转换为整数") # 处理转换错误
else:
print("未找到活动ID项") # 如果项为空,输出提示
def create_activity(self):
# 打开创建活动的窗口,传入 ActivityManager 实例
activity_form = ActivityForm(self.ui, self, activity_id=None)
activity_form.exec_() # 阻塞模式,等待窗口关闭后继续执行
def update_activity(self):
# 打开编辑活动的窗口传入活动ID
activity_form = ActivityForm(self.ui,self, activity_id=config.activityid)
activity_form.exec_() # 阻塞模式,等待窗口关闭后继续执行
def delete_activity(self):
try:
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432") as conn:
with conn.cursor() as cur:
# 删除与活动关联的注册记录
cur.execute("DELETE FROM registrations WHERE activity_id = %s", (config.activityid,))
cur.execute("DELETE FROM activities WHERE activityid = %s", (config.activityid,))
conn.commit()
self.load_data() # 重新加载活动数据
except Exception as e:
print(f"Error deleting activity: {e}")
def register_activity(self):
try:
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432") as conn:
with conn.cursor() as cur:
cur.execute("SELECT COUNT(*) FROM registrations WHERE user_id = %s AND activity_id = %s",
(config.user_now, config.activityid))
if cur.fetchone()[0] > 0:
self.show_message("你已经过报名活动", "请不要重复报名活动", QMessageBox.Information)
return
cur.execute("INSERT INTO registrations (user_id, activity_id) VALUES (%s, %s)",
(config.user_now, config.activityid))
cur.execute(
"UPDATE activities SET registration_count = registration_count + 1 WHERE activityid = %s",
(config.activityid,))
# 获取活动的积分
cur.execute("SELECT activity_points FROM activities WHERE activityid = %s", (config.activityid,))
activity_points = cur.fetchone()[0]
conn.commit()
self.Store.update_user_points(config.user_now, activity_points)
self.load_data()
self.show_message("报名成功", f"您已成功报名该活动,并获得 {activity_points} 积分!",
QMessageBox.Information)
except Exception as e:
print(f"Error registering for activity: {e}")
def load_data(self):
# 选中一行
self.ui.active_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
# 禁用整个表格的编辑
self.ui.active_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
# 建立数据库连接
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1", port="5432")
try:
cur = conn.cursor()
# 执行查询
cur.execute(
"SELECT ActivityID, ActivityName, ActivityDateTime, Location, Details, registration_count, activity_points FROM Activities ORDER BY ActivityID ASC") #用order按活动id排序
# 获取结果
rows = cur.fetchall()
# 设置表格行数
self.ui.active_table.setRowCount(len(rows))
# 填充表格
# 遍历每一行数据并填充到QTableWidget中
for row_index, row_data in enumerate(rows):
for column_index, item in enumerate(row_data):
# 创建QTableWidgetItem并设置为字符串格式
table_item = QtWidgets.QTableWidgetItem(str(item))
# 将item设置到相应的单元格
self.ui.active_table.setItem(row_index, column_index, table_item)
# 隐藏行号
self.ui.active_table.verticalHeader().setVisible(False)
except Exception as e:
print("Error loading data:", e)
def show_message(self, title, message, icon=QMessageBox.Information):
# 创建一个消息框并设置标题、内容和图标
msg = QtWidgets.QMessageBox()
msg.setWindowTitle(title)
msg.setText(message)
msg.setIcon(icon)
msg.exec_()
def search(self):
# 获取搜索框中的文本
search_text = self.ui.search_line_edit.text()
# 确保输入不为空
if not search_text:
self.show_message("请输入搜索内容", "请输入搜索内容", QMessageBox.Information)
return
self.ui.active_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.ui.active_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.ui.active_table.verticalHeader().setVisible(False)
# 建立数据库连接
try:
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432")
cur = conn.cursor()
# 使用搜索框中的文本进行模糊查询LIKE
query = """
SELECT ActivityID, ActivityName, ActivityDateTime, Location, Details, registration_count
FROM Activities
WHERE ActivityName LIKE %s OR Location LIKE %s OR CAST(ActivityID AS TEXT) LIKE %s
ORDER BY ActivityID ASC
"""
# 将 ActivityID 转换为文本类型进行模糊查询
search_param = f"%{search_text}%"
cur.execute(query, (search_param, search_param, search_param))
# 获取查询结果
rows = cur.fetchall()
# 如果没有找到任何匹配的活动
if not rows:
self.show_message("没有找到匹配的活动", "没有找到匹配的活动,请尝试其他关键字", QMessageBox.Information)
return
# 设置表格行数
self.ui.active_table.setRowCount(len(rows))
# 填充表格
for row_index, row_data in enumerate(rows):
if len(row_data) != 6:
print(f"Unexpected data structure at row {row_index}: {row_data}")
continue
for column_index, item in enumerate(row_data):
table_item = QTableWidgetItem(str(item))
self.ui.active_table.setItem(row_index, column_index, table_item)
except Exception as e:
print("Error searching for activities:", e)
self.show_message("查询错误", f"发生错误: {e}", QMessageBox.Critical)
finally:
# 关闭数据库连接
if conn:
conn.close()
def view_registered_activities(self):
# 获取当前用户ID
user_id = config.user_now
# 确保用户ID存在
if not user_id:
self.show_message("无效用户ID", "用户ID无效请重新登录", QMessageBox.Warning)
return
self.ui.active_table.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
self.ui.active_table.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.ui.active_table.verticalHeader().setVisible(False)
# 建立数据库连接
try:
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432")
cur = conn.cursor()
# 查询用户已报名的活动
query = """
SELECT a.ActivityID, a.ActivityName, a.ActivityDateTime, a.Location, a.Details, a.registration_count
FROM Activities a
JOIN Registrations r ON a.ActivityID = r.Activity_ID
WHERE r.User_ID = %s
ORDER BY a.ActivityID ASC
"""
cur.execute(query, (user_id,))
# 获取查询结果
rows = cur.fetchall()
# 如果用户没有报名任何活动
if not rows:
self.show_message("无报名活动", "没有找到您报名的活动,请先报名活动", QMessageBox.Information)
return
# 设置表格行数
self.ui.active_table.setRowCount(len(rows))
# 填充表格
for row_index, row_data in enumerate(rows):
for column_index, item in enumerate(row_data):
table_item = QTableWidgetItem(str(item))
self.ui.active_table.setItem(row_index, column_index, table_item)
except Exception as e:
self.show_message("错误", f"获取报名活动时发生错误: {e}", QMessageBox.Critical)
finally:
# 关闭数据库连接
if conn:
conn.close()
from PyQt5.QtWidgets import QFormLayout, QLineEdit, QDateTimeEdit, QPushButton, QVBoxLayout, QDialog
from PyQt5.QtCore import QDateTime
from PyQt5.QtGui import QFont
from PyQt5.QtCore import Qt
import psycopg2
import config
class ActivityForm(QDialog):
def __init__(self, ui, activity_manager, activity_id=None):
super().__init__()
self.ui = ui
self.activity_manager = activity_manager # 保存传入的 ActivityManager 实例
self.activity_id = activity_id # 如果是编辑模式则传入活动ID
self.init_ui()
if self.activity_id:
self.load_activity_data(self.activity_id)
def init_ui(self):
# Set the window title
self.setWindowTitle("创建/编辑活动")
# Set the window size and minimum size
self.setMinimumSize(500, 400)
self.setMaximumSize(600, 500)
# Set window font
font = QFont("Microsoft YaHei", 10)
self.setFont(font)
# Create layout and form
layout = QFormLayout()
# Create form elements
self.lineEdit_activeid = QLineEdit()
self.lineEdit_actvename = QLineEdit()
self.lineEdit_activelocation = QLineEdit()
self.dateTimeEdit = QDateTimeEdit()
self.lineEdit_activedatil = QLineEdit()
self.lineEdit_activepoint = QLineEdit() # 新增积分输入框
# Set default activity time to current datetime
self.dateTimeEdit.setDateTime(QDateTime.currentDateTime())
# Apply QSS styles to the input fields
input_style = """
QLineEdit {
border: 1px solid #ccc;
padding: 5px;
font-size: 14px;
}
"""
self.lineEdit_activeid.setStyleSheet(input_style)
self.lineEdit_actvename.setStyleSheet(input_style)
self.lineEdit_activelocation.setStyleSheet(input_style)
self.dateTimeEdit.setStyleSheet(input_style)
self.lineEdit_activedatil.setStyleSheet(input_style)
self.lineEdit_activepoint.setStyleSheet(input_style) # 为积分输入框设置样式
# Add form elements to layout
layout.addRow("活动ID:", self.lineEdit_activeid)
layout.addRow("活动名称:", self.lineEdit_actvename)
layout.addRow("活动地点:", self.lineEdit_activelocation)
layout.addRow("活动时间:", self.dateTimeEdit)
layout.addRow("活动详情:", self.lineEdit_activedatil)
layout.addRow("活动积分:", self.lineEdit_activepoint) # 显示积分输入框
# Create the save button
self.save_button = QPushButton("保存")
self.save_button.setStyleSheet("""
QPushButton {
background-color: #4CAF50;
color: white;
font-size: 16px;
padding: 10px 20px;
border-radius: 8px;
border: none;
}
QPushButton:hover {
background-color: #45a049;
}
QPushButton:pressed {
padding-top: 8px;
padding-left: 8px;
}
""")
self.save_button.clicked.connect(self.save_activity)
# Add the save button to the layout
layout.addWidget(self.save_button)
# Set spacing and alignment
layout.setSpacing(20) # Add some space between form elements
layout.setLabelAlignment(Qt.AlignRight) # Right-align labels
# Set the main layout for the dialog
self.setLayout(layout)
# Set dialog background and border
self.setStyleSheet("""
QDialog {
background-color: #f7f7f7;
border: 2px solid #ccc;
border-radius: 12px;
}
""")
def load_activity_data(self, activity_id):
"""加载现有活动的数据,用于编辑"""
try:
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1", port="5432") as conn:
with conn.cursor() as cur:
cur.execute("SELECT activityid, activityname, location, activitydatetime, details FROM activities WHERE activityid = %s", (activity_id,))
row = cur.fetchone()
if row:
self.lineEdit_activeid.setText(str(row[0]))
self.lineEdit_actvename.setText(row[1])
self.lineEdit_activelocation.setText(row[2])
self.dateTimeEdit.setDateTime(row[3]) # 需要根据格式调整日期时间
self.lineEdit_activedatil.setText(row[4])
except Exception as e:
print(f"Error loading activity data: {e}")
from PyQt5.QtWidgets import QMessageBox
def save_activity(self):
"""保存活动,判断是创建还是编辑"""
activeid = self.lineEdit_activeid.text()
activename = self.lineEdit_actvename.text()
activelocation = self.lineEdit_activelocation.text()
activetime = self.dateTimeEdit.dateTime().toPyDateTime()
activedatil = self.lineEdit_activedatil.text()
activepoint = self.lineEdit_activepoint.text() # 获取活动积分
# 确保积分是一个数字
try:
activepoint = int(activepoint) # 将积分转换为整数
except ValueError:
self.show_message("错误", "活动积分必须是有效的数字!", QMessageBox.Warning)
return
try:
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432") as conn:
with conn.cursor() as cur:
if self.activity_id:
# 编辑模式,不允许修改 activityid只更新其他字段
if activeid != str(self.activity_id):
self.show_message("错误", "活动ID不能修改", QMessageBox.Warning)
return
# 更新活动(不修改 activityid更新积分字段
cur.execute("""
UPDATE activities
SET activityname = %s, location = %s, activitydatetime = %s, details = %s, activity_points = %s
WHERE activityid = %s
""", (activename, activelocation, activetime, activedatil, activepoint, self.activity_id))
else:
# 创建新活动时检查活动ID或活动名称是否已经存在
cur.execute("SELECT COUNT(*) FROM activities WHERE activityid = %s", (activeid,))
if cur.fetchone()[0] > 0:
self.show_message("错误", "活动ID已存在请选择不同的活动ID", QMessageBox.Warning)
return
cur.execute("SELECT COUNT(*) FROM activities WHERE activityname = %s", (activename,))
if cur.fetchone()[0] > 0:
self.show_message("错误", "活动名称已存在,请选择不同的活动名称!", QMessageBox.Warning)
return
# 创建新活动,包含积分字段
cur.execute(
"INSERT INTO activities (activityid, activityname, location, activitydatetime, details, activity_points) VALUES (%s, %s, %s, %s, %s, %s)",
(activeid, activename, activelocation, activetime, activedatil, activepoint))
conn.commit()
self.activity_manager.load_data() # 通过传入的 activity_manager 调用 load_data()
self.accept() # 关闭窗口
except Exception as e:
print(f"Error saving activity: {e}")
self.show_message("错误", f"保存活动时发生错误: {e}", QMessageBox.Critical)
def show_message(self, title, message, icon=QMessageBox.Information):
"""显示消息框"""
msg = QMessageBox()
msg.setWindowTitle(title)
msg.setText(message)
msg.setIcon(icon)
msg.exec_()

@ -0,0 +1,5 @@
# config.py
user_now = ''
account_list = []
password_list = []
activityid = 0

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

@ -0,0 +1,296 @@
# -*- coding: utf-8 -*-
# Form implementation generated from reading ui file 'login.ui'
#
# Created by: PyQt5 UI code generator 5.15.11
#
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
# run again. Do not edit this file unless you know what you are doing.
from PyQt5 import QtCore, QtGui, QtWidgets
class Ui_LoginWindow(object):
def setupUi(self, LoginWindow):
LoginWindow.setObjectName("LoginWindow")
LoginWindow.resize(806, 700)
self.centralwidget = QtWidgets.QWidget(LoginWindow)
self.centralwidget.setObjectName("centralwidget")
self.frame = QtWidgets.QFrame(self.centralwidget)
self.frame.setGeometry(QtCore.QRect(50, 100, 331, 411))
self.frame.setStyleSheet("#frame{\n"
"border-image: url(:/picture/picture/孤独寂寞冷.png);\n"
"border-ridius:20px;}")
self.frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame.setObjectName("frame")
self.label = QtWidgets.QLabel(self.frame)
self.label.setGeometry(QtCore.QRect(20, 0, 251, 61))
self.label.setMinimumSize(QtCore.QSize(251, 61))
self.label.setStyleSheet("color: rgb(0, 0, 0);\n"
"font: 20pt \"方正舒体\";")
self.label.setObjectName("label")
self.frame_2 = QtWidgets.QFrame(self.centralwidget)
self.frame_2.setGeometry(QtCore.QRect(370, 100, 341, 411))
self.frame_2.setStyleSheet("background-color: rgb(255, 255, 255);")
self.frame_2.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_2.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_2.setObjectName("frame_2")
self.pushButton = QtWidgets.QPushButton(self.frame_2)
self.pushButton.setGeometry(QtCore.QRect(270, 10, 81, 31))
self.pushButton.setStyleSheet("QPushButton{\n"
" border:none;\n"
"}\n"
"QPushButton:hover{\n"
" padding-bottom:5px;\n"
"}")
self.pushButton.setText("")
icon = QtGui.QIcon()
icon.addPixmap(QtGui.QPixmap(":/icon/picture/close.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton.setIcon(icon)
self.pushButton.setIconSize(QtCore.QSize(30, 30))
self.pushButton.setObjectName("pushButton")
self.frame_3 = QtWidgets.QFrame(self.frame_2)
self.frame_3.setGeometry(QtCore.QRect(0, 40, 301, 350))
self.frame_3.setMinimumSize(QtCore.QSize(301, 350))
self.frame_3.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_3.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_3.setObjectName("frame_3")
self.verticalLayout = QtWidgets.QVBoxLayout(self.frame_3)
self.verticalLayout.setContentsMargins(0, 0, 0, 0)
self.verticalLayout.setObjectName("verticalLayout")
self.frame_4 = QtWidgets.QFrame(self.frame_3)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(6)
sizePolicy.setHeightForWidth(self.frame_4.sizePolicy().hasHeightForWidth())
self.frame_4.setSizePolicy(sizePolicy)
self.frame_4.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_4.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_4.setObjectName("frame_4")
self.verticalLayout_3 = QtWidgets.QVBoxLayout(self.frame_4)
self.verticalLayout_3.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_3.setObjectName("verticalLayout_3")
self.frame_6 = QtWidgets.QFrame(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(5)
sizePolicy.setHeightForWidth(self.frame_6.sizePolicy().hasHeightForWidth())
self.frame_6.setSizePolicy(sizePolicy)
self.frame_6.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_6.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_6.setObjectName("frame_6")
self.horizontalLayout_2 = QtWidgets.QHBoxLayout(self.frame_6)
self.horizontalLayout_2.setContentsMargins(0, 0, 0, 0)
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
self.stackedWidget_2 = QtWidgets.QStackedWidget(self.frame_6)
self.stackedWidget_2.setStyleSheet("QLineEdit{\n"
" \n"
" background-color: rgba(255, 255, 255,0);\n"
" border:none;\n"
"border-bottom:1px solid black;\n"
"}\n"
"QPushButton{\n"
" \n"
" background-color: rgb(0, 0, 0);\n"
" color: rgb(255, 255, 255);\n"
" border-radius:7px;\n"
" font: 20pt \"方正舒体\";\n"
"}\n"
"QPushButton:pressed{\n"
" padding-top:5px;\n"
" padding-left:5px;\n"
"}")
self.stackedWidget_2.setObjectName("stackedWidget_2")
self.login = QtWidgets.QWidget()
self.login.setObjectName("login")
self.verticalLayout_4 = QtWidgets.QVBoxLayout(self.login)
self.verticalLayout_4.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_4.setObjectName("verticalLayout_4")
self.LineEdit_L_account = QtWidgets.QLineEdit(self.login)
self.LineEdit_L_account.setMinimumSize(QtCore.QSize(0, 35))
self.LineEdit_L_account.setObjectName("LineEdit_L_account")
self.verticalLayout_4.addWidget(self.LineEdit_L_account)
self.LineEdit_L_password = QtWidgets.QLineEdit(self.login)
self.LineEdit_L_password.setMinimumSize(QtCore.QSize(0, 35))
self.LineEdit_L_password.setEchoMode(QtWidgets.QLineEdit.Password)
self.LineEdit_L_password.setObjectName("LineEdit_L_password")
self.verticalLayout_4.addWidget(self.LineEdit_L_password)
self.PushButtom_L_sure = QtWidgets.QPushButton(self.login)
self.PushButtom_L_sure.setMinimumSize(QtCore.QSize(0, 40))
self.PushButtom_L_sure.setObjectName("PushButtom_L_sure")
self.verticalLayout_4.addWidget(self.PushButtom_L_sure)
self.stackedWidget_2.addWidget(self.login)
self.register_2 = QtWidgets.QWidget()
self.register_2.setObjectName("register_2")
self.verticalLayout_5 = QtWidgets.QVBoxLayout(self.register_2)
self.verticalLayout_5.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_5.setObjectName("verticalLayout_5")
self.LineEdit_R_account = QtWidgets.QLineEdit(self.register_2)
self.LineEdit_R_account.setMinimumSize(QtCore.QSize(0, 30))
self.LineEdit_R_account.setObjectName("LineEdit_R_account")
self.verticalLayout_5.addWidget(self.LineEdit_R_account)
self.LineEdit_R_password = QtWidgets.QLineEdit(self.register_2)
self.LineEdit_R_password.setMinimumSize(QtCore.QSize(0, 30))
self.LineEdit_R_password.setObjectName("LineEdit_R_password")
self.verticalLayout_5.addWidget(self.LineEdit_R_password)
self.LineEdit_R_password1 = QtWidgets.QLineEdit(self.register_2)
self.LineEdit_R_password1.setMinimumSize(QtCore.QSize(0, 30))
self.LineEdit_R_password1.setObjectName("LineEdit_R_password1")
self.verticalLayout_5.addWidget(self.LineEdit_R_password1)
self.QPushButtom_R_sure = QtWidgets.QPushButton(self.register_2)
self.QPushButtom_R_sure.setMinimumSize(QtCore.QSize(0, 40))
self.QPushButtom_R_sure.setObjectName("QPushButtom_R_sure")
self.verticalLayout_5.addWidget(self.QPushButtom_R_sure)
self.stackedWidget_2.addWidget(self.register_2)
self.horizontalLayout_2.addWidget(self.stackedWidget_2)
self.verticalLayout_3.addWidget(self.frame_6)
self.frame_7 = QtWidgets.QFrame(self.frame_4)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.frame_7.sizePolicy().hasHeightForWidth())
self.frame_7.setSizePolicy(sizePolicy)
self.frame_7.setStyleSheet("QPushButton{\n"
" border:none;\n"
"}\n"
"QPushButton:pressed{\n"
" padding-top:5px;\n"
" padding-left:5px;\n"
"}")
self.frame_7.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_7.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_7.setObjectName("frame_7")
self.horizontalLayout = QtWidgets.QHBoxLayout(self.frame_7)
self.horizontalLayout.setObjectName("horizontalLayout")
self.pushButton_Login = QtWidgets.QPushButton(self.frame_7)
self.pushButton_Login.setText("")
icon1 = QtGui.QIcon()
icon1.addPixmap(QtGui.QPixmap(":/icon/picture/登录.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_Login.setIcon(icon1)
self.pushButton_Login.setIconSize(QtCore.QSize(30, 30))
self.pushButton_Login.setObjectName("pushButton_Login")
self.horizontalLayout.addWidget(self.pushButton_Login)
self.pushButton_Register = QtWidgets.QPushButton(self.frame_7)
self.pushButton_Register.setText("")
icon2 = QtGui.QIcon()
icon2.addPixmap(QtGui.QPixmap(":/icon/picture/登录注册.png"), QtGui.QIcon.Normal, QtGui.QIcon.Off)
self.pushButton_Register.setIcon(icon2)
self.pushButton_Register.setIconSize(QtCore.QSize(30, 30))
self.pushButton_Register.setObjectName("pushButton_Register")
self.horizontalLayout.addWidget(self.pushButton_Register)
self.verticalLayout_3.addWidget(self.frame_7)
self.verticalLayout.addWidget(self.frame_4)
self.frame_5 = QtWidgets.QFrame(self.frame_3)
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred, QtWidgets.QSizePolicy.Expanding)
sizePolicy.setHorizontalStretch(0)
sizePolicy.setVerticalStretch(1)
sizePolicy.setHeightForWidth(self.frame_5.sizePolicy().hasHeightForWidth())
self.frame_5.setSizePolicy(sizePolicy)
self.frame_5.setStyleSheet("color: rgb(255, 0, 0);\n"
"font: 12pt \"幼圆\";")
self.frame_5.setFrameShape(QtWidgets.QFrame.StyledPanel)
self.frame_5.setFrameShadow(QtWidgets.QFrame.Raised)
self.frame_5.setObjectName("frame_5")
self.verticalLayout_10 = QtWidgets.QVBoxLayout(self.frame_5)
self.verticalLayout_10.setContentsMargins(0, 0, 0, 0)
self.verticalLayout_10.setSpacing(0)
self.verticalLayout_10.setObjectName("verticalLayout_10")
self.stackedWidget = QtWidgets.QStackedWidget(self.frame_5)
self.stackedWidget.setObjectName("stackedWidget")
self.page = QtWidgets.QWidget()
self.page.setObjectName("page")
self.verticalLayout_6 = QtWidgets.QVBoxLayout(self.page)
self.verticalLayout_6.setObjectName("verticalLayout_6")
self.stackedWidget.addWidget(self.page)
self.page_3 = QtWidgets.QWidget()
self.page_3.setObjectName("page_3")
self.verticalLayout_7 = QtWidgets.QVBoxLayout(self.page_3)
self.verticalLayout_7.setObjectName("verticalLayout_7")
self.label_3 = QtWidgets.QLabel(self.page_3)
self.label_3.setObjectName("label_3")
self.verticalLayout_7.addWidget(self.label_3)
self.stackedWidget.addWidget(self.page_3)
self.page_4 = QtWidgets.QWidget()
self.page_4.setObjectName("page_4")
self.verticalLayout_8 = QtWidgets.QVBoxLayout(self.page_4)
self.verticalLayout_8.setObjectName("verticalLayout_8")
self.label_4 = QtWidgets.QLabel(self.page_4)
self.label_4.setStyleSheet("color: rgb(0, 0, 0);")
self.label_4.setObjectName("label_4")
self.verticalLayout_8.addWidget(self.label_4)
self.stackedWidget.addWidget(self.page_4)
self.page_2 = QtWidgets.QWidget()
self.page_2.setObjectName("page_2")
self.verticalLayout_2 = QtWidgets.QVBoxLayout(self.page_2)
self.verticalLayout_2.setObjectName("verticalLayout_2")
self.label_2 = QtWidgets.QLabel(self.page_2)
self.label_2.setStyleSheet("font: 12pt \"幼圆\"\n"
"")
self.label_2.setObjectName("label_2")
self.verticalLayout_2.addWidget(self.label_2)
self.stackedWidget.addWidget(self.page_2)
self.page_5 = QtWidgets.QWidget()
self.page_5.setObjectName("page_5")
self.verticalLayout_9 = QtWidgets.QVBoxLayout(self.page_5)
self.verticalLayout_9.setObjectName("verticalLayout_9")
self.label_5 = QtWidgets.QLabel(self.page_5)
self.label_5.setStyleSheet("color: rgb(0, 0, 0);")
self.label_5.setObjectName("label_5")
self.verticalLayout_9.addWidget(self.label_5)
self.stackedWidget.addWidget(self.page_5)
self.page_6 = QtWidgets.QWidget()
self.page_6.setObjectName("page_6")
self.label_6 = QtWidgets.QLabel(self.page_6)
self.label_6.setGeometry(QtCore.QRect(40, 10, 191, 31))
self.label_6.setObjectName("label_6")
self.stackedWidget.addWidget(self.page_6)
self.page_7 = QtWidgets.QWidget()
self.page_7.setObjectName("page_7")
self.verticalLayout_11 = QtWidgets.QVBoxLayout(self.page_7)
self.verticalLayout_11.setObjectName("verticalLayout_11")
self.label_7 = QtWidgets.QLabel(self.page_7)
self.label_7.setObjectName("label_7")
self.verticalLayout_11.addWidget(self.label_7, 0, QtCore.Qt.AlignHCenter)
self.stackedWidget.addWidget(self.page_7)
self.page_8 = QtWidgets.QWidget()
self.page_8.setObjectName("page_8")
self.verticalLayout_12 = QtWidgets.QVBoxLayout(self.page_8)
self.verticalLayout_12.setObjectName("verticalLayout_12")
self.label_8 = QtWidgets.QLabel(self.page_8)
self.label_8.setObjectName("label_8")
self.verticalLayout_12.addWidget(self.label_8)
self.stackedWidget.addWidget(self.page_8)
self.verticalLayout_10.addWidget(self.stackedWidget, 0, QtCore.Qt.AlignHCenter)
self.verticalLayout.addWidget(self.frame_5, 0, QtCore.Qt.AlignHCenter)
LoginWindow.setCentralWidget(self.centralwidget)
self.toolBar = QtWidgets.QToolBar(LoginWindow)
self.toolBar.setObjectName("toolBar")
LoginWindow.addToolBar(QtCore.Qt.TopToolBarArea, self.toolBar)
self.retranslateUi(LoginWindow)
self.stackedWidget.setCurrentIndex(0)
self.pushButton.clicked.connect(LoginWindow.close) # type: ignore
QtCore.QMetaObject.connectSlotsByName(LoginWindow)
def retranslateUi(self, LoginWindow):
_translate = QtCore.QCoreApplication.translate
LoginWindow.setWindowTitle(_translate("LoginWindow", "MainWindow"))
self.label.setText(_translate("LoginWindow", "活动管理系统"))
self.LineEdit_L_account.setPlaceholderText(_translate("LoginWindow", "账号:"))
self.LineEdit_L_password.setPlaceholderText(_translate("LoginWindow", "密码:"))
self.PushButtom_L_sure.setText(_translate("LoginWindow", "确认"))
self.LineEdit_R_account.setPlaceholderText(_translate("LoginWindow", "账号:"))
self.LineEdit_R_password.setPlaceholderText(_translate("LoginWindow", "密码:"))
self.LineEdit_R_password1.setPlaceholderText(_translate("LoginWindow", "确认密码:"))
self.QPushButtom_R_sure.setText(_translate("LoginWindow", "注册"))
self.label_3.setText(_translate("LoginWindow", " 密码不一致!"))
self.label_4.setText(_translate("LoginWindow", " 账号注册成功!"))
self.label_2.setText(_translate("LoginWindow", " 账号或密码不能为空"))
self.label_5.setText(_translate("LoginWindow", " 登录成功 "))
self.label_6.setText(_translate("LoginWindow", " 账号已存在"))
self.label_7.setText(_translate("LoginWindow", "账号已存在"))
self.label_8.setText(_translate("LoginWindow", " 账号或密码错误"))
self.toolBar.setWindowTitle(_translate("LoginWindow", "toolBar"))
import resource_rc

@ -0,0 +1,589 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>LoginWindow</class>
<widget class="QMainWindow" name="LoginWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>806</width>
<height>700</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QFrame" name="frame">
<property name="geometry">
<rect>
<x>50</x>
<y>100</y>
<width>331</width>
<height>411</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">#frame{
border-image: url(:/picture/picture/孤独寂寞冷.png);
border-ridius:20px;}</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>0</y>
<width>251</width>
<height>61</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>251</width>
<height>61</height>
</size>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(0, 0, 0);
font: 20pt &quot;方正舒体&quot;;</string>
</property>
<property name="text">
<string>活动管理系统</string>
</property>
</widget>
</widget>
<widget class="QFrame" name="frame_2">
<property name="geometry">
<rect>
<x>370</x>
<y>100</y>
<width>341</width>
<height>411</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">background-color: rgb(255, 255, 255);</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<widget class="QPushButton" name="pushButton">
<property name="geometry">
<rect>
<x>270</x>
<y>10</y>
<width>81</width>
<height>31</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border:none;
}
QPushButton:hover{
padding-bottom:5px;
}</string>
</property>
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/icon/picture/close.png</normaloff>:/icon/picture/close.png</iconset>
</property>
<property name="iconSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
</widget>
<widget class="QFrame" name="frame_3">
<property name="geometry">
<rect>
<x>0</x>
<y>40</y>
<width>301</width>
<height>350</height>
</rect>
</property>
<property name="minimumSize">
<size>
<width>301</width>
<height>350</height>
</size>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_4">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>6</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_3">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QFrame" name="frame_6">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>5</verstretch>
</sizepolicy>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout_2">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QStackedWidget" name="stackedWidget_2">
<property name="styleSheet">
<string notr="true">QLineEdit{
background-color: rgba(255, 255, 255,0);
border:none;
border-bottom:1px solid black;
}
QPushButton{
background-color: rgb(0, 0, 0);
color: rgb(255, 255, 255);
border-radius:7px;
font: 20pt &quot;方正舒体&quot;;
}
QPushButton:pressed{
padding-top:5px;
padding-left:5px;
}</string>
</property>
<widget class="QWidget" name="login">
<layout class="QVBoxLayout" name="verticalLayout_4">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="LineEdit_L_account">
<property name="minimumSize">
<size>
<width>0</width>
<height>35</height>
</size>
</property>
<property name="placeholderText">
<string>账号:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="LineEdit_L_password">
<property name="minimumSize">
<size>
<width>0</width>
<height>35</height>
</size>
</property>
<property name="echoMode">
<enum>QLineEdit::Password</enum>
</property>
<property name="placeholderText">
<string>密码:</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="PushButtom_L_sure">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>确认</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="register_2">
<layout class="QVBoxLayout" name="verticalLayout_5">
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item>
<widget class="QLineEdit" name="LineEdit_R_account">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="placeholderText">
<string>账号:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="LineEdit_R_password">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="placeholderText">
<string>密码:</string>
</property>
</widget>
</item>
<item>
<widget class="QLineEdit" name="LineEdit_R_password1">
<property name="minimumSize">
<size>
<width>0</width>
<height>30</height>
</size>
</property>
<property name="placeholderText">
<string>确认密码:</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="QPushButtom_R_sure">
<property name="minimumSize">
<size>
<width>0</width>
<height>40</height>
</size>
</property>
<property name="text">
<string>注册</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QFrame" name="frame_7">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
border:none;
}
QPushButton:pressed{
padding-top:5px;
padding-left:5px;
}</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QPushButton" name="pushButton_Login">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/icon/picture/登录.png</normaloff>:/icon/picture/登录.png</iconset>
</property>
<property name="iconSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="pushButton_Register">
<property name="text">
<string/>
</property>
<property name="icon">
<iconset resource="resource.qrc">
<normaloff>:/icon/picture/登录注册.png</normaloff>:/icon/picture/登录注册.png</iconset>
</property>
<property name="iconSize">
<size>
<width>30</width>
<height>30</height>
</size>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</item>
<item alignment="Qt::AlignHCenter">
<widget class="QFrame" name="frame_5">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Expanding">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="styleSheet">
<string notr="true">color: rgb(255, 0, 0);
font: 12pt &quot;幼圆&quot;;</string>
</property>
<property name="frameShape">
<enum>QFrame::StyledPanel</enum>
</property>
<property name="frameShadow">
<enum>QFrame::Raised</enum>
</property>
<layout class="QVBoxLayout" name="verticalLayout_10">
<property name="spacing">
<number>0</number>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item alignment="Qt::AlignHCenter">
<widget class="QStackedWidget" name="stackedWidget">
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="page">
<layout class="QVBoxLayout" name="verticalLayout_6"/>
</widget>
<widget class="QWidget" name="page_3">
<layout class="QVBoxLayout" name="verticalLayout_7">
<item>
<widget class="QLabel" name="label_3">
<property name="text">
<string> 密码不一致!</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_4">
<layout class="QVBoxLayout" name="verticalLayout_8">
<item>
<widget class="QLabel" name="label_4">
<property name="styleSheet">
<string notr="true">color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string> 账号注册成功!</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_2">
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="QLabel" name="label_2">
<property name="styleSheet">
<string notr="true">font: 12pt &quot;幼圆&quot;
</string>
</property>
<property name="text">
<string> 账号或密码不能为空</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_5">
<layout class="QVBoxLayout" name="verticalLayout_9">
<item>
<widget class="QLabel" name="label_5">
<property name="styleSheet">
<string notr="true">color: rgb(0, 0, 0);</string>
</property>
<property name="text">
<string> 登录成功 </string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_6">
<widget class="QLabel" name="label_6">
<property name="geometry">
<rect>
<x>40</x>
<y>10</y>
<width>191</width>
<height>31</height>
</rect>
</property>
<property name="text">
<string> 账号已存在</string>
</property>
</widget>
</widget>
<widget class="QWidget" name="page_7">
<layout class="QVBoxLayout" name="verticalLayout_11">
<item alignment="Qt::AlignHCenter">
<widget class="QLabel" name="label_7">
<property name="text">
<string>账号已存在</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="page_8">
<layout class="QVBoxLayout" name="verticalLayout_12">
<item>
<widget class="QLabel" name="label_8">
<property name="text">
<string> 账号或密码错误</string>
</property>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</widget>
<widget class="QToolBar" name="toolBar">
<property name="windowTitle">
<string>toolBar</string>
</property>
<attribute name="toolBarArea">
<enum>TopToolBarArea</enum>
</attribute>
<attribute name="toolBarBreak">
<bool>false</bool>
</attribute>
</widget>
</widget>
<resources>
<include location="resource.qrc"/>
</resources>
<connections>
<connection>
<sender>pushButton</sender>
<signal>clicked()</signal>
<receiver>LoginWindow</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>701</x>
<y>135</y>
</hint>
<hint type="destinationlabel">
<x>729</x>
<y>54</y>
</hint>
</hints>
</connection>
</connections>
</ui>

@ -0,0 +1,221 @@
import psycopg2
from login import *
from PyQt5.QtWidgets import QApplication, QMainWindow
import sys
from interface import *
from activemanager import ActivityManager # 导入活动管理类
import config
from activearrangement import Active_arrangement
from store import Store
NONE = None
class LoginWindow(QMainWindow):
def __init__(self):
super().__init__() # 调用父类的初始化方法
self.ui = Ui_LoginWindow() # 创建一个 UI 界面的实例
self.ui.setupUi(self) # 设置 UI 界面
# 去掉窗口边框
self.setWindowFlag(QtCore.Qt.FramelessWindowHint) # 设置窗口为无边框模式
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # 设置窗口背景为透明
# 创建阴影效果
self.shadow = QtWidgets.QGraphicsDropShadowEffect(self) # 创建一个阴影效果对象
self.shadow.setOffset(0, 0) # 设置阴影偏移量为 (0, 0)
self.shadow.setBlurRadius(10) # 设置阴影模糊半径为 10 像素
self.shadow.setColor(QtCore.Qt.black) # 设置阴影颜色为黑色
self.ui.frame.setGraphicsEffect(self.shadow) # 将阴影效果应用到指定的框架 (frame)
# 设置样式表,去掉边框并设置透明背景
self.setStyleSheet("background-color: rgba(255, 255, 255, 0); border: none;") # 设置窗口背景为完全透明,并去掉边框
# 强制窗口固定大小
# self.setFixedSize(self.size()) # (注释掉的代码)如果需要,可以取消注释以固定窗口大小为当前大小
self.ui.pushButton_Login.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(0))
self.ui.pushButton_Register.clicked.connect(lambda: self.ui.stackedWidget_2.setCurrentIndex(1))
self.ui.PushButtom_L_sure.clicked.connect(self.login)
self.ui.QPushButtom_R_sure.clicked.connect(self.register)
self.show() # 显窗口
def register(self):
account = self.ui.LineEdit_R_account.text()
password = self.ui.LineEdit_R_password.text()
password1 = self.ui.LineEdit_R_password1.text()
global user_now
if len(account) == 0 or len(password ) == 0 or len(password1) == 0:
self.ui.stackedWidget.setCurrentIndex(3)
elif password1 != password:
self.ui.stackedWidget.setCurrentIndex(1)
else:
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432")
cur = conn.cursor()
# 查询现有账户
cur.execute("SELECT accounts FROM users")
existing_accounts = cur.fetchall() # 获取所有账户
account_list = [row[0] for row in existing_accounts] # 提取账户名列表
if account in account_list:
self.ui.stackedWidget.setCurrentIndex(6) # 账户已存在
else:
# 插入新账户并获取新用户的userid
cur.execute("INSERT INTO users (accounts, passwords) VALUES (%s, %s) RETURNING userid",
(account, password))
new_user_id = cur.fetchone()[0] # 获取新插入的用户ID
# 插入用户积分,假设初始积分为 0
initial_points = 0
cur.execute("INSERT INTO user_points (user_id, total_points) VALUES (%s, %s)",
(new_user_id, initial_points))
conn.commit() # 提交更改
self.ui.stackedWidget.setCurrentIndex(2) # 注册成功页面
def login(self):
# 获取用户输入的账户和密码
account = self.ui.LineEdit_L_account.text()
password = self.ui.LineEdit_L_password.text()
# 检查账户或密码是否为空
if len(account) == 0 or len(password) == 0:
self.ui.stackedWidget.setCurrentIndex(3) # 显示错误消息,提示账户或密码不能为空
return
try:
# 连接数据库
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432")
cur = conn.cursor()
# 查询用户账户和密码
cur.execute("SELECT userid, accounts, passwords FROM users WHERE accounts = %s", (account,))
row = cur.fetchone()
if row:
user_id, db_account, db_password = row
# 验证账户和密码是否匹配
if account == db_account and password == db_password:
config.user_now = user_id # 将用户ID存储在全局变量中
self.win = MainWindow() # 打开主窗口
self.win.show() # 显示主窗口
self.close() # 关闭登录窗口
else:
self.ui.stackedWidget.setCurrentIndex(7) # 显示错误消息,提示账户或密码错误
else:
self.ui.stackedWidget.setCurrentIndex(7) # 显示错误消息,提示账户不存在
conn.commit()
except Exception as e:
print(f"Error logging in: {e}")
finally:
# 关闭数据库连接
if conn:
conn.close()
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.ui = Ui_MainWindow() # 假设 Ui_MainWindow 已经定义
self.ui.setupUi(self)
# 设置窗口属性
self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
self.setAttribute(QtCore.Qt.WA_TranslucentBackground)
self.setStyleSheet("background-color: rgba(255, 255, 255, 0); border: none;")
# 创建活动管理实例
self.activity_manager = ActivityManager(self.ui)
self.activity_arrangement = Active_arrangement(self.ui)
self.Store = Store(self.ui)
# 初始化拖动相关变量
self.mouse_press_pos = None
# 连接信号和槽
self.setup_signals()
self.activity_manager.load_data() # 使用活动管理类加载数据
self.Store.setup_ui()
self.Store.load_data()
self.Store.load_user_info()
self.show() # 显示窗口
def setup_signals(self):
self.ui.pushButton_active_manage.clicked.connect(lambda: self.ui.stackedWidget.setCurrentIndex(0))
self.ui.pushButton_active_arrange.clicked.connect(lambda: self.ui.stackedWidget.setCurrentIndex(1))
self.ui.pushButton_home.clicked.connect(lambda: self.ui.stackedWidget.setCurrentIndex(2))
self.ui.pushButton_profile.clicked.connect(lambda: self.ui.stackedWidget.setCurrentIndex(4))
self.ui.pushButton_store.clicked.connect(lambda: (self.ui.stackedWidget.setCurrentIndex(3), self.Store.load_user_info()))
self.ui.pushButton_logout.clicked.connect(self.logout)
self.ui.pushButton_m_sure.clicked.connect(self.change_password)
self.ui.pushButton_creat_active.clicked.connect(self.activity_manager.create_activity) # 更新为活动管理方法
self.ui.pushButton_correct_active.clicked.connect(self.activity_manager.update_activity) # 更新为活动管理方法
self.ui.pushButton_delete_active.clicked.connect(
self.activity_manager.delete_activity) # 传递活动ID
self.ui.pushButton_baoming.clicked.connect(self.activity_manager.register_activity)
self.ui.active_table.cellClicked.connect(self.activity_manager.handle_double_click) # 连接双击事件
self.ui.pushButton_4.clicked.connect(self.activity_manager.search)
self.ui.pushButton_5.clicked.connect(self.activity_manager.view_registered_activities)
self.ui.pushButton_6.clicked.connect(self.activity_manager.load_data)
def mousePressEvent(self, event):
if event.button() == QtCore.Qt.LeftButton and self.ui.frame_4.geometry().contains(event.pos()):
self.mouse_press_pos = event.globalPos() - self.pos()
event.accept()
def mouseMoveEvent(self, event):
if self.mouse_press_pos is not None:
self.move(event.globalPos() - self.mouse_press_pos)
event.accept()
def mouseReleaseEvent(self, event):
if event.button() == QtCore.Qt.LeftButton:
self.mouse_press_pos = NONE
event.accept()
def logout(self):
global user_now
self.close()
self.login = LoginWindow() # 假设 LoginWindow 已经定义
user_now = ''
def change_password(self):
global user_now
password = self.ui.lineEdit_password.text()
confirm_password = self.ui.lineEdit_password2.text()
if not password or not confirm_password:
self.ui.stackedWidget_2.setCurrentIndex(1) # 显示错误消息
return
if password == confirm_password:
try:
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432") as conn:
with conn.cursor() as cur:
cur.execute("UPDATE users SET passwords = %s WHERE accounts = %s", (password, user_now))
conn.commit()
self.ui.stackedWidget_2.setCurrentIndex(2) # 显示成功消息
except Exception as e:
print(f"Error changing password: {e}")
self.ui.stackedWidget_2.setCurrentIndex(1)
if __name__ == '__main__':
app = QApplication(sys.argv)
win = LoginWindow()
sys.exit(app.exec_())

@ -0,0 +1,19 @@
class Settings():
# 应用程序设置
# ///////////////////////////////////////////////////////////////
ENABLE_CUSTOM_TITLE_BAR = True # 启用自定义标题栏
MENU_WIDTH = 240 # 菜单宽度(单位:像素)
LEFT_BOX_WIDTH = 240 # 左侧框的宽度(单位:像素)
RIGHT_BOX_WIDTH = 240 # 右侧框的宽度(单位:像素)
TIME_ANIMATION = 500 # 动画时间(单位:毫秒)
# 左右框按钮的背景颜色
BTN_LEFT_BOX_COLOR = "background-color: rgb(44, 49, 58);" # 左侧框按钮的背景颜色
BTN_RIGHT_BOX_COLOR = "background-color: #ff79c6;" # 右侧框按钮的背景颜色
# 菜单选中状态的样式表
MENU_SELECTED_STYLESHEET = """
border-left: 22px solid qlineargradient(spread:pad, x1:0.034, y1:0, x2:0.216, y2:0,
stop:0.499 rgba(255, 121, 198, 255), stop:0.5 rgba(85, 170, 255, 0)); # 左侧边框样式
background-color: rgb(40, 44, 52); # 菜单选中时的背景颜色
"""

@ -0,0 +1,297 @@
# ///////////////////////////////////////////////////////////////
#
# BY: WANDERSON M.PIMENTA
# PROJECT MADE WITH: Qt Designer and PySide6
# V: 1.0.0
#
# This project can be used freely for all uses, as long as they maintain the
# respective credits only in the Python scripts, any information in the visual
# interface (GUI) can be modified without any implication.
#
# There are limitations on Qt licenses if you want to use your products
# commercially, I recommend reading them on the official website:
# https://doc.qt.io/qtforpython/licenses.html
#
# ///////////////////////////////////////////////////////////////
import psycopg2
import activemanager
from login import *
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5.QtWidgets import QApplication, QMainWindow, QFrame, QHBoxLayout, QWidget
from PyQt5.QtCore import QRect, QSize
from PyQt5.QtGui import QCursor
from PyQt5.Qt import Qt
from PyQt5 import QtCore
import sys
class Widgets:
# Placeholder for the Widgets class, implement your widget creation logic here.
def top(self, parent):
self.top = QWidget(parent)
self.top.setObjectName("top")
self.top.setStyleSheet("background: lightgray") # Change as needed
self.top.setGeometry(0, 0, parent.width(), 10)
self.top_left = QWidget(parent)
self.top_left.setObjectName("top_left")
self.top_left.setStyleSheet("background: gray") # Change as needed
self.top_left.setGeometry(0, 0, 10, 10)
self.top_right = QWidget(parent)
self.top_right.setObjectName("top_right")
self.top_right.setStyleSheet("background: gray") # Change as needed
self.top_right.setGeometry(parent.width() - 10, 0, 10, 10)
def bottom(self, parent):
self.bottom = QWidget(parent)
self.bottom.setObjectName("bottom")
self.bottom.setStyleSheet("background: lightgray") # Change as needed
self.bottom.setGeometry(0, parent.height() - 10, parent.width(), 10)
self.bottom_left = QWidget(parent)
self.bottom_left.setObjectName("bottom_left")
self.bottom_left.setStyleSheet("background: gray") # Change as needed
self.bottom_left.setGeometry(0, parent.height() - 10, 10, 10)
self.bottom_right = QWidget(parent)
self.bottom_right.setObjectName("bottom_right")
self.bottom_right.setStyleSheet("background: gray") # Change as needed
self.bottom_right.setGeometry(parent.width() - 10, parent.height() - 10, 10, 10)
def left(self, parent):
self.leftgrip = QWidget(parent)
self.leftgrip.setObjectName("left")
self.leftgrip.setStyleSheet("background: lightgray") # Change as needed
self.leftgrip.setGeometry(0, 10, 10, parent.height() - 20)
def right(self, parent):
self.rightgrip = QWidget(parent)
self.rightgrip.setObjectName("right")
self.rightgrip.setStyleSheet("background: lightgray") # Change as needed
self.rightgrip.setGeometry(parent.width() - 10, 10, 10, parent.height() - 20)
class CustomGrip(QWidget):
def __init__(self, parent, position, disable_color=False):
super().__init__(parent) # Use super to call QWidget's constructor
self.parent = parent
self.wi = Widgets()
# Show top grip
if position == QtCore.Qt.TopEdge:
self.wi.top(self)
self.setGeometry(0, 0, self.parent.width(), 10)
self.setMaximumHeight(10)
# Resize top
self.wi.top.mouseMoveEvent = self.create_resize_handler("top")
# Enable color
if disable_color:
self.set_style_transparent(["top_left", "top_right", "top"])
# Show bottom grip
elif position == QtCore.Qt.BottomEdge:
self.wi.bottom(self)
self.setGeometry(0, self.parent.height() - 10, self.parent.width(), 10)
self.setMaximumHeight(10)
# Resize bottom
self.wi.bottom.mouseMoveEvent = self.create_resize_handler("bottom")
# Enable color
if disable_color:
self.set_style_transparent(["bottom_left", "bottom_right", "bottom"])
# Show left grip
elif position == QtCore.Qt.LeftEdge:
self.wi.left(self)
self.setGeometry(0, 10, 10, self.parent.height())
self.setMaximumWidth(10)
# Resize left
self.wi.leftgrip.mouseMoveEvent = self.create_resize_handler("left")
# Enable color
if disable_color:
self.set_style_transparent(["left"])
# Show right grip
elif position == QtCore.Qt.RightEdge:
self.wi.right(self)
self.setGeometry(self.parent.width() - 10, 10, 10, self.parent.height())
self.setMaximumWidth(10)
# Resize right
self.wi.rightgrip.mouseMoveEvent = self.create_resize_handler("right")
# Enable color
if disable_color:
self.set_style_transparent(["right"])
def set_style_transparent(self, widgets):
for widget in widgets:
getattr(self.wi, widget).setStyleSheet("background: transparent")
def create_resize_handler(self, edge):
def resize(event):
delta = event.pos()
if edge == "top":
height = max(self.parent.minimumHeight(), self.parent.height() - delta.y())
geo = self.parent.geometry()
geo.setTop(geo.bottom() - height)
self.parent.setGeometry(geo)
event.accept()
elif edge == "bottom":
height = max(self.parent.minimumHeight(), self.parent.height() + delta.y())
self.parent.resize(self.parent.width(), height)
event.accept()
elif edge == "left":
width = max(self.parent.minimumWidth(), self.parent.width() - delta.x())
geo = self.parent.geometry()
geo.setLeft(geo.right() - width)
self.parent.setGeometry(geo)
event.accept()
elif edge == "right":
width = max(self.parent.minimumWidth(), self.parent.width() + delta.x())
self.parent.resize(width, self.parent.height())
event.accept()
return resize
class Widgets(object):
def top(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
# Create the container frame
self.container_top = QFrame(Form)
self.container_top.setObjectName(u"container_top")
self.container_top.setGeometry(QRect(0, 0, 500, 10))
self.container_top.setMinimumSize(QSize(0, 10))
self.container_top.setMaximumSize(QSize(16777215, 10))
self.container_top.setFrameShape(QFrame.NoFrame)
self.container_top.setFrameShadow(QFrame.Raised)
# Create the horizontal layout for the top container
self.top_layout = QHBoxLayout(self.container_top)
self.top_layout.setSpacing(0)
self.top_layout.setObjectName(u"top_layout")
self.top_layout.setContentsMargins(0, 0, 0, 0)
# Create the left grip
self.top_left = QFrame(self.container_top)
self.top_left.setObjectName(u"top_left")
self.top_left.setMinimumSize(QSize(10, 10))
self.top_left.setMaximumSize(QSize(10, 10))
self.top_left.setCursor(QCursor(Qt.SizeFDiagCursor))
self.top_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
self.top_left.setFrameShape(QFrame.NoFrame)
self.top_left.setFrameShadow(QFrame.Raised)
self.top_layout.addWidget(self.top_left)
# Create the main top bar
self.top = QFrame(self.container_top)
self.top.setObjectName(u"top")
self.top.setCursor(QCursor(Qt.SizeVerCursor))
self.top.setStyleSheet(u"background-color: rgb(85, 255, 255);")
self.top.setFrameShape(QFrame.NoFrame)
self.top.setFrameShadow(QFrame.Raised)
self.top_layout.addWidget(self.top)
# Create the right grip
self.top_right = QFrame(self.container_top)
self.top_right.setObjectName(u"top_right")
self.top_right.setMinimumSize(QSize(10, 10))
self.top_right.setMaximumSize(QSize(10, 10))
self.top_right.setCursor(QCursor(Qt.SizeBDiagCursor))
self.top_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
self.top_right.setFrameShape(QFrame.NoFrame)
self.top_right.setFrameShadow(QFrame.Raised)
self.top_layout.addWidget(self.top_right)
def bottom(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
# Create the bottom container
self.container_bottom = QFrame(Form)
self.container_bottom.setObjectName(u"container_bottom")
self.container_bottom.setGeometry(QRect(0, Form.height() - 10, 500, 10))
self.container_bottom.setMinimumSize(QSize(0, 10))
self.container_bottom.setMaximumSize(QSize(16777215, 10))
self.container_bottom.setFrameShape(QFrame.NoFrame)
self.container_bottom.setFrameShadow(QFrame.Raised)
# Create the horizontal layout for the bottom container
self.bottom_layout = QHBoxLayout(self.container_bottom)
self.bottom_layout.setSpacing(0)
self.bottom_layout.setObjectName(u"bottom_layout")
self.bottom_layout.setContentsMargins(0, 0, 0, 0)
# Create the left grip
self.bottom_left = QFrame(self.container_bottom)
self.bottom_left.setObjectName(u"bottom_left")
self.bottom_left.setMinimumSize(QSize(10, 10))
self.bottom_left.setMaximumSize(QSize(10, 10))
self.bottom_left.setCursor(QCursor(Qt.SizeBDiagCursor))
self.bottom_left.setStyleSheet(u"background-color: rgb(33, 37, 43);")
self.bottom_left.setFrameShape(QFrame.NoFrame)
self.bottom_left.setFrameShadow(QFrame.Raised)
self.bottom_layout.addWidget(self.bottom_left)
# Create the main bottom bar
self.bottom = QFrame(self.container_bottom)
self.bottom.setObjectName(u"bottom")
self.bottom.setCursor(QCursor(Qt.SizeVerCursor))
self.bottom.setStyleSheet(u"background-color: rgb(85, 170, 0);")
self.bottom.setFrameShape(QFrame.NoFrame)
self.bottom.setFrameShadow(QFrame.Raised)
self.bottom_layout.addWidget(self.bottom)
# Create the right grip
self.bottom_right = QFrame(self.container_bottom)
self.bottom_right.setObjectName(u"bottom_right")
self.bottom_right.setMinimumSize(QSize(10, 10))
self.bottom_right.setMaximumSize(QSize(10, 10))
self.bottom_right.setCursor(QCursor(Qt.SizeFDiagCursor))
self.bottom_right.setStyleSheet(u"background-color: rgb(33, 37, 43);")
self.bottom_right.setFrameShape(QFrame.NoFrame)
self.bottom_right.setFrameShadow(QFrame.Raised)
self.bottom_layout.addWidget(self.bottom_right)
def left(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
# Create the left grip
self.leftgrip = QFrame(Form)
self.leftgrip.setObjectName(u"left")
self.leftgrip.setGeometry(QRect(0, 10, 10, 480))
self.leftgrip.setMinimumSize(QSize(10, 0))
self.leftgrip.setCursor(QCursor(Qt.SizeHorCursor))
self.leftgrip.setStyleSheet(u"background-color: rgb(255, 121, 198);")
self.leftgrip.setFrameShape(QFrame.NoFrame)
self.leftgrip.setFrameShadow(QFrame.Raised)
def right(self, Form):
if not Form.objectName():
Form.setObjectName(u"Form")
# Resize the form and create the right grip
Form.resize(500, 500)
self.rightgrip = QFrame(Form)
self.rightgrip.setObjectName(u"right")
self.rightgrip.setGeometry(QRect(Form.width() - 10, 0, 10, 500))
self.rightgrip.setMinimumSize(QSize(10, 0))
self.rightgrip.setCursor(QCursor(Qt.SizeHorCursor))
self.rightgrip.setStyleSheet(u"background-color: rgb(255, 0, 127);")
self.rightgrip.setFrameShape(QFrame.NoFrame)
self.rightgrip.setFrameShadow(QFrame.Raised)

@ -0,0 +1,65 @@
import sys
import psycopg2
from PyQt5.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QFrame, QLabel, QPushButton, QWidget
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle("积分商城")
self.setGeometry(100, 100, 800, 600)
self.central_widget = QWidget()
self.setCentralWidget(self.central_widget)
self.layout = QVBoxLayout(self.central_widget)
# 调用加载数据的方法
self.load_data()
def load_data(self):
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1", port="5432")
try:
cur = conn.cursor()
# 指定需要的列
cur.execute("SELECT name, points,image_url FROM products")
rows = cur.fetchall()
print(f"Fetched {len(rows)} products.")
for row in rows:
product_id, name, price = row # 这里应与查询的列数一致
self.add_product_to_widget(name, price)
except Exception as e:
print(f"Error: {e}")
finally:
cur.close()
conn.close()
def add_product_to_widget(self, name, price):
# 创建商品框架
product_frame = QFrame(self)
product_frame.setFrameShape(QFrame.Box)
product_layout = QVBoxLayout(product_frame)
# 商品图片(这里用一个占位符代替)
product_image = QLabel("商品图片", self)
product_layout.addWidget(product_image)
# 商品名称
name_label = QLabel(name, self)
product_layout.addWidget(name_label)
# 商品价格
price_label = QLabel(f"价格: {price} 积分", self)
product_layout.addWidget(price_label)
# 兑换按钮
exchange_button = QPushButton("兑换", self)
product_layout.addWidget(exchange_button)
# 将商品框架添加到主布局
self.layout.addWidget(product_frame)
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec_())

@ -0,0 +1,297 @@
import activemanager
from login import *
from PyQt5.QtWidgets import QApplication, QMainWindow
from PyQt5 import QtCore
import sys
from interface import *
from PyQt5.QtCore import QSize
from PyQt5.QtCore import QPropertyAnimation, QEasingCurve # 使用 PyQt5
from modules.app_settings import Settings
from PyQt5.QtWidgets import QGraphicsDropShadowEffect
from modules.custom_grips import CustomGrip
from main import *
# GLOBALS
# ///////////////////////////////////////////////////////////////
GLOBAL_STATE = False
GLOBAL_TITLE_BAR = True
class UIFunctions(MainWindow):
# 最大恢复
# ///////////////////////////////////////////////////////////////
def maximize_restore(self):
global GLOBAL_STATE
status = GLOBAL_STATE
if status == False:
self.showMaximized()
GLOBAL_STATE = True
self.ui.appMargins.setContentsMargins(0, 0, 0, 0)
self.ui.pushButton_3.setToolTip("Restore")
self.ui.pushButton_3.setIcon("D:\Desktop\学习\software\software\picture\cil-window-restore.png")
self.ui.frame_size_grip.hide()
self.left_grip.hide()
self.right_grip.hide()
self.top_grip.hide()
self.bottom_grip.hide()
else:
GLOBAL_STATE = False
self.showNormal()
self.resize(self.width() + 1, self.height() + 1)
self.ui.appMargins.setContentsMargins(10, 10, 10, 10)
self.ui.maximizeRestoreAppBtn.setToolTip("Maximize")
self.ui.maximizeRestoreAppBtn.setIcon("D:\Desktop\学习\software\software\picture\全屏.png")
self.ui.frame_size_grip.show()
self.left_grip.show()
self.right_grip.show()
self.top_grip.show()
self.bottom_grip.show()
# RETURN STATUS
# ///////////////////////////////////////////////////////////////
def returStatus(self):
return GLOBAL_STATE
# SET STATUS
# ///////////////////////////////////////////////////////////////
def setStatus(self, status):
global GLOBAL_STATE
GLOBAL_STATE = status
# TOGGLE MENU
# ///////////////////////////////////////////////////////////////
def toggleMenu(self, enable):
if enable:
# GET WIDTH
width = self.ui.left_mune.width()
maxExtend = Settings.MENU_WIDTH
standard = 60
# SET MAX WIDTH
if width == 60:
widthExtended = maxExtend
else:
widthExtended = standard
# 创建一个属性动画对象,用于控制左侧菜单的最小宽度
self.animation = QPropertyAnimation(self.ui.left_mune, b"minimumWidth")
# 设置动画的持续时间,单位为毫秒
self.animation.setDuration(Settings.TIME_ANIMATION) # 动画的总时间
# 设置动画的起始值,当前左侧菜单的宽度
self.animation.setStartValue(width) # 动画开始时的最小宽度
# 设置动画的结束值,左侧菜单扩展后的宽度
self.animation.setEndValue(widthExtended) # 动画结束时的最小宽度
# 设置动画的缓动曲线,这里使用的是 InOutQuart 曲线
self.animation.setEasingCurve(QEasingCurve.InOutQuart) # 动画效果,平滑过渡
# 启动动画
self.animation.start() # 开始执行动画
# TOGGLE LEFT BOX
# ///////////////////////////////////////////////////////////////
def toggleLeftBox(self, enable):
# 获取当前宽度
width = self.ui.left_mune.width()
widthRightBox = self.ui.extraRightBox.width()
maxExtend = Settings.LEFT_BOX_WIDTH
color = Settings.BTN_LEFT_BOX_COLOR
# 计算新的宽度
widthExtended = maxExtend if enable and width == 0 else 0
# 获取当前按钮样式
style = self.ui.toggleLeftBox.styleSheet()
# 更新按钮样式
if widthExtended == maxExtend:
# 扩展左侧框时设置按钮颜色
self.ui.toggleLeftBox.setStyleSheet(style + color)
if widthRightBox != 0:
self.updateRightButtonStyle(remove_color=True)
else:
# 收起左侧框时重置按钮颜色
self.ui.toggleLeftBox.setStyleSheet(style.replace(color, ''))
# 启动动画
UIFunctions.start_box_animation(self, width, widthRightBox, widthExtended, "left")
def updateRightButtonStyle(self, remove_color=False):
"""更新右侧按钮的样式"""
style = self.ui.settingsTopBtn.styleSheet()
if remove_color:
self.ui.settingsTopBtn.setStyleSheet(style.replace(Settings.BTN_RIGHT_BOX_COLOR, ''))
else:
# 这里可以添加更多样式更新逻辑
pass
# TOGGLE RIGHT BOX
# ///////////////////////////////////////////////////////////////
def toggleRightBox(self, enable):
if enable:
# GET WIDTH
width = self.ui.extraRightBox.width()
widthLeftBox = self.ui.extraLeftBox.width()
maxExtend = Settings.RIGHT_BOX_WIDTH
color = Settings.BTN_RIGHT_BOX_COLOR
standard = 0
# GET BTN STYLE
style = self.ui.settingsTopBtn.styleSheet()
# SET MAX WIDTH
if width == 0:
widthExtended = maxExtend
# SELECT BTN
self.ui.settingsTopBtn.setStyleSheet(style + color)
if widthLeftBox != 0:
style = self.ui.toggleLeftBox.styleSheet()
self.ui.toggleLeftBox.setStyleSheet(style.replace(Settings.BTN_LEFT_BOX_COLOR, ''))
else:
widthExtended = standard
# RESET BTN
self.ui.settingsTopBtn.setStyleSheet(style.replace(color, ''))
UIFunctions.start_box_animation(self, widthLeftBox, width, "right")
def start_box_animation(self, left_box_width, right_box_width, direction):
right_width = 0
left_width = 0
# Check values
if left_box_width == 0 and direction == "left":
left_width = 240
else:
left_width = 0
# Check values
if right_box_width == 0 and direction == "right":
right_width = 240
else:
right_width = 0
# ANIMATION LEFT BOX
self.left_box = QPropertyAnimation(self.ui.extraLeftBox, b"minimumWidth")
self.left_box.setDuration(Settings.TIME_ANIMATION)
self.left_box.setStartValue(left_box_width)
self.left_box.setEndValue(left_width)
self.left_box.setEasingCurve(QEasingCurve.InOutQuart)
# ANIMATION RIGHT BOX
self.right_box = QPropertyAnimation(self.ui.extraRightBox, b"minimumWidth")
self.right_box.setDuration(Settings.TIME_ANIMATION)
self.right_box.setStartValue(right_box_width)
self.right_box.setEndValue(right_width)
self.right_box.setEasingCurve(QEasingCurve.InOutQuart)
# GROUP ANIMATION
self.group = QParallelAnimationGroup()
self.group.addAnimation(self.left_box)
self.group.addAnimation(self.right_box)
self.group.start()
# SELECT/DESELECT MENU
# ///////////////////////////////////////////////////////////////
# SELECT
def selectMenu(getStyle):
select = getStyle + Settings.MENU_SELECTED_STYLESHEET
return select
# DESELECT
def deselectMenu(getStyle):
deselect = getStyle.replace(Settings.MENU_SELECTED_STYLESHEET, "")
return deselect
# START SELECTION
def selectStandardMenu(self, widget):
for w in self.ui.topMenu.findChildren(QPushButton):
if w.objectName() == widget:
w.setStyleSheet(UIFunctions.selectMenu(w.styleSheet()))
# RESET SELECTION
def resetStyle(self, widget):
for w in self.ui.topMenu.findChildren(QPushButton):
if w.objectName() != widget:
w.setStyleSheet(UIFunctions.deselectMenu(w.styleSheet()))
# IMPORT THEMES FILES QSS/CSS
# ///////////////////////////////////////////////////////////////
def theme(self, file, useCustomTheme):
if useCustomTheme:
str = open(file, 'r').read()
self.ui.styleSheet.setStyleSheet(str)
# START - GUI DEFINITIONS
# ///////////////////////////////////////////////////////////////
def uiDefinitions(self):
# 双击最大化/还原窗口的事件处理
if Settings.ENABLE_CUSTOM_TITLE_BAR:
# 启用自定义标题栏
self.setWindowFlags(QtCore.Qt.FramelessWindowHint) # 设置窗口为无边框
self.setAttribute(QtCore.Qt.WA_TranslucentBackground) # 设置窗口背景透明
# 移动窗口 / 最大化 / 还原窗口
def moveWindow(event):
# 如果当前窗口是最大化状态,则还原为正常状态
if UIFunctions.returStatus(self):
UIFunctions.maximize_restore(self)
# 移动窗口
if event.buttons() == QtCore.Qt.LeftButton: # 判断是否按下左键
self.move(self.pos() + event.globalPos() - self.dragPos) # 移动窗口
self.dragPos = event.globalPos() # 更新拖动位置
event.accept() # 接受事件
# 设置鼠标移动事件处理器
self.ui.frame_4.mouseMoveEvent = moveWindow
# 自定义窗口边缘控件(用于调整大小)
self.left_grip = CustomGrip(self, QtCore.Qt.LeftEdge, True)
self.right_grip = CustomGrip(self, QtCore.Qt.RightEdge, True)
self.top_grip = CustomGrip(self, QtCore.Qt.TopEdge, True)
self.bottom_grip = CustomGrip(self, QtCore.Qt.BottomEdge, True)
else:
# 如果不启用自定义标题栏,则设置应用程序边距并隐藏控制按钮
self.ui.appMargins.setContentsMargins(0, 0, 0, 0) # 设置边距为0
self.ui.minimizeAppBtn.hide() # 隐藏最小化按钮
self.ui.maximizeRestoreAppBtn.hide() # 隐藏最大化/还原按钮
self.ui.closeAppBtn.hide() # 隐藏关闭按钮
self.ui.frame_size_grip.hide() # 隐藏大小调整控件
# 设置窗口阴影效果
#self.shadow = QtCore.QGraphicsDropShadowEffect(self) # 创建阴影效果
#self.shadow.setBlurRadius(17) # 设置模糊半径
#self.shadow.setXOffset(0) # 设置X轴偏移
#self.shadow.setYOffset(0) # 设置Y轴偏移
#self.shadow.setColor(QtCore.QColor(0, 0, 0, 150)) # 设置阴影颜色
#self.ui.bgApp.setGraphicsEffect(self.shadow) # 应用阴影效果
# 设置窗口调整大小的控件
#self.sizegrip = QtCore.QSizeGrip(self.ui.frame_size_grip) # 创建大小调整控件
#self.sizegrip.setStyleSheet("width: 20px; height: 20px; margin 0px; padding 0px;") # 设置样式
# 最大化/还原按钮的点击事件
self.ui.pushButton_3.clicked.connect(lambda: UIFunctions.maximize_restore(self)) # 点击时最大化/还原窗口
def resize_grips(self):
# 调整边缘控件的大小
if Settings.ENABLE_CUSTOM_TITLE_BAR:
# 设置各边缘控件的位置和大小
self.left_grip.setGeometry(0, 10, 10, self.height()) # 左侧控件
self.right_grip.setGeometry(self.width() - 10, 10, 10, self.height()) # 右侧控件
self.top_grip.setGeometry(0, 0, self.width(), 10) # 顶部控件
self.bottom_grip.setGeometry(0, self.height() - 10, self.width(), 10) # 底部控件
# ///////////////////////////////////////////////////////////////
# END - GUI DEFINITIONS

Binary file not shown.

After

Width:  |  Height:  |  Size: 370 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 22 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 112 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.6 KiB

@ -0,0 +1,55 @@
项目简介
这是一个基于 PyQt5 构建的桌面应用程序,主要用于用户登录、注册、活动管理及积分管理。系统通过与 PostgreSQL 数据库进行交互,管理用户信息和活动数据。用户可以在系统中创建、更新、删除活动,查看和注册感兴趣的活动。
系统功能
用户登录与注册:
用户可以通过输入用户名和密码进行登录,系统会在数据库中验证用户信息。
新用户可以通过输入用户名、密码及确认密码进行注册,系统会检查用户名是否已经存在。
支持修改密码功能,用户可以在个人设置中修改密码。
主界面:
登录成功后,用户进入主界面,主界面包含多个模块,如活动管理、商店、个人资料等。
支持无边框窗口,界面背景透明,并且可拖动窗口。
提供丰富的导航功能,用户可以切换不同的页面来管理活动、查看商店等。
活动管理:
用户可以创建、更新、删除和注册活动,所有活动数据都存储在数据库中。
支持活动数据的增、删、查、改操作,用户可以查看和管理已创建的活动。
数据库交互:
用户信息(用户名、密码)存储在 PostgreSQL 数据库中。
用户积分数据也存储在数据库中,用户可以查看自己的积分并进行相应的管理。
系统还支持活动数据的管理,所有创建的活动都存储在数据库中。
环境配置
依赖库
PyQt5: 用于构建图形用户界面。
安装命令:
pip install PyQt5
psycopg2: 用于与 PostgreSQL 数据库进行交互。
安装命令:
pip install psycopg2
QtCore: 这是 PyQt5 的一部分,提供了窗口属性、拖拽等功能。
数据库配置
安装 PostgreSQL:
确保已安装并启动 PostgreSQL 数据库。
数据库配置:
创建名为 DataMY 的数据库。
导入数据库文件
配置文件:
在 config.py 中配置数据库连接信息(可根据需要进行修改):
python
复制代码
user_now = None # 当前登录的用户ID
启动应用
在main.py里面运行
运行环境:
使用 Python 3.x 版本运行本项目。
将所有 Python 文件及 .ui 文件(例如 Ui_LoginWindow 和 Ui_MainWindow放在同一目录下。

@ -0,0 +1,17 @@
<RCC>
<qresource prefix="icon">
<file>picture/搜索.png</file>
<file>picture/全屏.png</file>
<file>picture/exit.png</file>
<file>picture/登录注册.png</file>
<file>picture/登录.png</file>
<file>picture/close.png</file>
<file>picture/active.png</file>
<file>picture/mini.png</file>
</qresource>
<qresource prefix="picture">
<file>picture/孤独寂寞冷.png</file>
<file>picture/login.jpg</file>
<file>picture/R-C.jpg</file>
</qresource>
</RCC>

File diff suppressed because it is too large Load Diff

@ -0,0 +1,394 @@
from PyQt5 import QtWidgets, QtGui, QtCore
import psycopg2
import config
from interface import * # 导入界面组件
from PyQt5.QtWidgets import QMessageBox, QTableWidgetItem
class Store:
def __init__(self, ui):
self.ui = ui
self.page_store = self.ui.page_store
self.store_frame = self.ui.store_frame
self.points_frame = self.ui.points_frame
self.record_frame = self.ui.record_frame
self.verticalLayout_33 = self.ui.verticalLayout_33
self.points_label = QtWidgets.QLabel("总积分: 0")
self.points_label.setAlignment(QtCore.Qt.AlignCenter)
self.items_per_row = 3 # 每行商品数
def setup_ui(self):
'''def clear_layout(layout):
while layout.count():
child = layout.takeAt(0)
if child.widget():
child.widget().deleteLater()
# 清理布局
if self.points_frame.layout():
clear_layout(self.points_frame.layout())'''
# 设置字体样式
self.points_label.setStyleSheet("""
font-size: 18px; /* 字体大小 */
font-weight: bold; /* 字体加粗 */
color: #4CAF50; /* 字体颜色(绿色) */
font-family: Arial, Helvetica, sans-serif; /* 字体家族 */
background-color: #f9f9f9; /* 背景颜色 */
border: 1px solid #ddd; /* 边框样式 */
border-radius: 8px; /* 圆角边框 */
padding: 10px; /* 内边距 */
""")
# 设置积分显示框的布局
if self.points_frame.layout() is None:
points_layout = QtWidgets.QVBoxLayout(self.points_frame)
points_layout.setContentsMargins(0, 0, 0, 0)
points_layout.setSpacing(10)
else:
points_layout = self.points_frame.layout()
points_layout.addWidget(self.points_label) # 将积分标签添加到布局中
# 在 record_frame 中添加购买记录显示(使用 QTableWidget
if not hasattr(self, 'purchase_table'): # 只创建一次
self.purchase_table = QtWidgets.QTableWidget() # 创建 QTableWidget 显示购买记录
self.purchase_table.setObjectName("purchase_table")
# 直接使用 record_frame 的布局来添加 purchase_table
if self.record_frame.layout() is None:
record_layout = QtWidgets.QVBoxLayout(self.record_frame)
record_layout.setContentsMargins(0, 0, 0, 0)
record_layout.setSpacing(5)
else:
record_layout = self.record_frame.layout()
record_layout.addWidget(self.purchase_table) # 将 QTableWidget 添加到布局中
# 确保 store_frame 布局存在
if self.store_frame.layout() is None:
store_layout = QtWidgets.QGridLayout(self.store_frame) # 使用 GridLayout 或其他布局
store_layout.setContentsMargins(0, 0, 0, 0) # 去除边距
store_layout.setSpacing(10) # 设置商品之间的间距
else:
store_layout = self.store_frame.layout()
# 设置商品展示区域
self.store_frame.setLayout(store_layout) # 如果没有设置过,设置布局
def load_data(self):
# 连接数据库并加载商品信息
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1", port="5432")
try:
cur = conn.cursor()
cur.execute("SELECT image_url, name, points FROM products") # 查询商品数据
rows = cur.fetchall()
print(f"Fetched {len(rows)} products.") # 调试信息:获取到多少个商品
self.clear_product_display() # 清空商品展示区域
# 将商品数据添加到界面中
for row in rows:
image_url, name, points = row
self.add_product_to_widget(image_url, name, points)
except Exception as e:
print(f"Error: {e}") # 如果有错误,打印错误信息
finally:
cur.close()
conn.close()
def clear_product_display(self):
# 清空商店页面的商品显示区域
for i in reversed(range(self.store_frame.layout().count())):
widget = self.store_frame.layout().itemAt(i).widget()
if widget is not None:
widget.deleteLater() # 删除每个商品的显示组件
def add_product_to_widget(self, image_url, name, points):
# 创建商品展示框架
product_frame = QtWidgets.QFrame(self.store_frame)
product_frame.setFrameShape(QtWidgets.QFrame.StyledPanel)
product_frame.setStyleSheet("padding: 10px; margin: 10px; border: 1px solid #ccc; border-radius: 5px;") # 样式
product_layout = QtWidgets.QVBoxLayout(product_frame)
# 商品图片
product_image = QtWidgets.QLabel()
pixmap = QtGui.QPixmap(image_url).scaled(150, 150, QtCore.Qt.KeepAspectRatio) # 图片缩放
product_image.setPixmap(pixmap)
product_layout.addWidget(product_image, alignment=QtCore.Qt.AlignCenter)
# 商品名称
name_label = QtWidgets.QLabel(name)
name_label.setAlignment(QtCore.Qt.AlignCenter)
product_layout.addWidget(name_label)
# 商品积分
points_label = QtWidgets.QLabel(f"积分: {points}")
points_label.setAlignment(QtCore.Qt.AlignCenter)
product_layout.addWidget(points_label)
# 兑换按钮
redeem_button = QtWidgets.QPushButton("兑换")
redeem_button.setStyleSheet("background-color: #4CAF50; color: white; border-radius: 5px;") # 按钮样式
product_layout.addWidget(redeem_button)
# 绑定兑换按钮事件
redeem_button.clicked.connect(lambda checked, p=points: self.redeem_product(name, p))
# 根据行列位置将商品框架添加到布局
total_items = self.store_frame.layout().count()
row = total_items // self.items_per_row
column = total_items % self.items_per_row
# 添加商品框架到布局
self.store_frame.layout().addWidget(product_frame, row, column)
def redeem_product(self, product_name, points, quantity=1):
# 处理商品兑换逻辑
conn = None
try:
# 连接数据库
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1", port="5432")
cur = conn.cursor()
# 获取当前用户积分
cur.execute("SELECT total_points FROM user_points WHERE user_id = %s", (config.user_now,))
result = cur.fetchone()
if result:
self.current_points = result[0]
# 判断积分是否足够
if self.current_points >= points:
self.current_points -= points # 扣除积分
# 获取商品的ID和库存
cur.execute("SELECT id, stock FROM products WHERE name = %s", (product_name,))
product_result = cur.fetchone()
if product_result:
product_id, stock = product_result
# 判断库存是否足够
if stock >= quantity:
# 更新商品库存
new_stock = stock - quantity
cur.execute("UPDATE products SET stock = %s WHERE id = %s", (new_stock, product_id))
# 开始数据库事务
cur.execute("BEGIN")
# 更新用户积分
cur.execute("UPDATE user_points SET total_points = %s WHERE user_id = %s", (self.current_points, config.user_now))
# 检查是否已经有购买记录,如果有,则合并数量
cur.execute("""
SELECT quantity FROM purchases
WHERE user_id = %s AND product_id = %s
""", (config.user_now, product_id))
existing_purchase = cur.fetchone()
if existing_purchase:
# 如果已经购买过该商品,则更新购买数量
new_quantity = existing_purchase[0] + quantity
cur.execute("""
UPDATE purchases
SET quantity = %s, purchase_date = NOW()
WHERE user_id = %s AND product_id = %s
""", (new_quantity, config.user_now, product_id))
else:
# 如果没有购买记录,则插入新的购买记录
cur.execute("""
INSERT INTO purchases (user_id, product_id, quantity, purchase_date)
VALUES (%s, %s, %s, NOW())
""", (config.user_now, product_id, quantity))
# 提交事务
conn.commit()
# 显示兑换成功消息
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(QtWidgets.QMessageBox.Information)
msg_box.setText(f"兑换产品: {product_name},成功!")
msg_box.setInformativeText(f"剩余积分: {self.current_points}\n剩余库存: {new_stock}")
msg_box.setWindowTitle("兑换成功")
msg_box.exec_()
self.load_user_info()
# 更新界面中的积分显示
if hasattr(self, 'points_label'):
self.points_label.setText(f"总积分: {self.current_points}") # 更新积分显示
else:
# 显示库存不足的消息
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(QtWidgets.QMessageBox.Warning)
msg_box.setText(f"兑换产品: {product_name},失败!")
msg_box.setInformativeText("库存不足。")
msg_box.setWindowTitle("兑换失败")
msg_box.exec_()
else:
# 如果找不到商品ID
raise ValueError("商品未找到")
else:
# 显示积分不足的警告消息
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(QtWidgets.QMessageBox.Warning)
msg_box.setText(f"兑换产品: {product_name},失败!")
msg_box.setInformativeText("积分不足。")
msg_box.setWindowTitle("兑换失败")
msg_box.exec_()
else:
# 如果找不到用户积分
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setText("用户积分未找到!")
msg_box.setWindowTitle("错误")
msg_box.exec_()
except psycopg2.Error as db_error:
# 捕获数据库相关的错误
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setText("数据库操作错误!")
msg_box.setInformativeText(f"错误信息: {db_error}")
msg_box.setWindowTitle("错误")
msg_box.exec_()
except Exception as e:
# 捕获其他未知的错误
msg_box = QtWidgets.QMessageBox()
msg_box.setIcon(QtWidgets.QMessageBox.Critical)
msg_box.setText("发生错误!")
msg_box.setInformativeText(f"错误信息: {e}")
msg_box.setWindowTitle("错误")
msg_box.exec_()
finally:
# 关闭数据库连接
if conn:
conn.close()
def show_message(self, title, message, icon):
msg_box = QMessageBox()
msg_box.setWindowTitle(title)
msg_box.setText(message)
msg_box.setIcon(icon)
msg_box.exec_()
def update_user_points(self,user_id, points_to_add):
"""
更新用户积分
"""
try:
with psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1",
port="5432") as conn:
with conn.cursor() as cur:
# 更新用户积分,并返回更新后的积分值
cur.execute("""
UPDATE user_points
SET total_points = total_points + %s
WHERE user_id = %s
RETURNING total_points
""", (points_to_add, user_id))
# 获取更新后的积分
total_points = cur.fetchone()[0] # 提取返回的 total_points 值
print(f"User Total Points: {total_points}") # 调试输出:打印用户积分
self.points_label.setText(f"总积分: {total_points}")
# 提交事务
conn.commit()
# 返回更新后的积分值如果不想操作UI
return total_points
except Exception as e:
print(f"Error updating user points: {e}")
# 此处可以处理错误,例如抛出异常或返回一个标记值
return None
def load_user_info(self):
# 连接数据库
conn = psycopg2.connect(database="DataMY", user="postgres", password="822520", host="127.0.0.1", port="5432")
try:
cur = conn.cursor()
# 获取用户的总积分
print(f"Fetching total points for user_id: {config.user_now}") # 调试输出:获取当前用户的积分
cur.execute("SELECT total_points FROM user_points WHERE user_id = %s", (config.user_now,)) # 查询当前用户的总积分
result = cur.fetchone() # 获取查询结果
if result:
total_points = result[0] # 获取积分值
print(f"User Total Points: {total_points}") # 调试输出:打印用户积分
# 仅在积分发生变化时更新显示
if self.points_label.text() != f"总积分: {total_points}":
self.points_label.setText(f"总积分: {total_points}") # 更新界面上的积分显示
else:
print("No total points found for this user.") # 调试输出:没有找到用户积分
self.points_label.setText("总积分: 0") # 如果没有积分数据显示为0
# 获取用户的购买记录及购买时间
print(f"Fetching purchase records for user_id: {config.user_now}") # 调试输出:获取当前用户的购买记录
cur.execute("""
SELECT p.name, pur.purchase_date, pur.quantity
FROM products p
JOIN purchases pur ON p.id = pur.product_id
WHERE pur.user_id = %s
ORDER BY pur.purchase_date DESC
""", (config.user_now,)) # 查询用户购买的商品名称、购买时间和数量,按购买日期降序排列
purchase_records = cur.fetchall() # 获取所有购买记录
# 合并相同商品的购买记录并显示数量
product_dict = {}
for record in purchase_records:
product_name = record[0]
purchase_date = record[1].strftime("%Y-%m-%d %H:%M:%S") # 格式化日期
quantity = record[2]
# 合并相同商品的数量
if product_name in product_dict:
product_dict[product_name]['quantity'] += quantity # 累加数量
else:
product_dict[product_name] = {'purchase_date': purchase_date, 'quantity': quantity}
# 使用 QTableWidget 来显示购买记录
if product_dict:
print(f"Fetched {len(product_dict)} unique products.") # 调试输出:打印唯一商品数量
# 清空当前表格内容
self.purchase_table.clearContents()
self.purchase_table.setRowCount(0)
# 设置表格列数和列名
self.purchase_table.setColumnCount(3) # 三列:商品名称、购买时间、数量
self.purchase_table.setHorizontalHeaderLabels(["商品名称", "购买时间", "数量"])
# 向表格中添加合并后的记录
for product_name, data in product_dict.items():
row_position = self.purchase_table.rowCount()
self.purchase_table.insertRow(row_position)
self.purchase_table.setItem(row_position, 0, QtWidgets.QTableWidgetItem(product_name))
self.purchase_table.setItem(row_position, 1, QtWidgets.QTableWidgetItem(data['purchase_date']))
self.purchase_table.setItem(row_position, 2, QtWidgets.QTableWidgetItem(str(data['quantity'])))
else:
print("No purchase records found for this user.") # 调试输出:没有找到购买记录
self.purchase_table.clearContents()
self.purchase_table.setRowCount(0)
self.purchase_table.setRowCount(1)
self.purchase_table.setItem(0, 0, QtWidgets.QTableWidgetItem("暂无购买记录"))
except Exception as e:
print(f"Error loading user info: {e}") # 如果出错,打印错误信息
finally:
cur.close() # 关闭数据库游标
conn.close() # 关闭数据库连接
Loading…
Cancel
Save