This commit is contained in:
2024-05-19 15:48:09 +08:00
parent 4a7406083d
commit 084f18051b
5 changed files with 256 additions and 0 deletions

67
textbook/README.md Normal file
View File

@ -0,0 +1,67 @@
# 快速打开电子教材
## 简介
用于在课堂上快速打开电子教材,支持多科目和多教材。
## 文件结构
- `main.py`:主程序文件,包含所有的界面和功能实现。
- `config.json`:配置文件,存储科目及其对应的教材文件路径。
## 依赖项
- Python 3.x
- PySide6
## 安装
1. 安装 Python 3.x。
2. 安装 PySide6
```bash
pip install PySide6
```
3. 克隆或下载此项目。
## 使用
1. 确保 `config.json` 配置文件存在,并且格式如下:
```json
{
"科目1": {
"教材1": "路径/到/文件1",
"教材2": "路径/到/文件2"
},
"科目2": {
"教材1": "路径/到/文件1",
"教材2": "路径/到/文件2"
}
}
```
2. 运行主程序:
```bash
python main.py
```
3. 点击圆形按钮打开主界面,选择科目并点击相应按钮打开文件。
## 配置文件
`config.json` 是一个 JSON 格式的配置文件,用于存储科目及其对应的教材文件路径。示例如下:
```json
{
"数学": {
"代数": "C:/教材/数学/代数.pdf",
"几何": "C:/教材/数学/几何.pdf"
},
"物理": {
"力学": "C:/教材/物理/力学.pdf",
"电学": "C:/教材/物理/电学.pdf"
}
}
```
## 注意事项
- 确保配置文件中的路径是有效的文件路径。
- 运行程序时需要保证 `config.json` 文件位于与 `main.py` 相同的目录下。
## 示例截图
![应用程序截图](screen1.png)
![应用程序截图](screen2.png)

173
textbook/app_1.py Normal file
View File

@ -0,0 +1,173 @@
from PySide6.QtWidgets import QApplication, QMainWindow, QPushButton, QTabWidget, QVBoxLayout, QWidget,QGraphicsDropShadowEffect,QLabel
from PySide6.QtCore import Qt, QPoint, QTimer
from PySide6.QtGui import QPainter, QBrush, QColor, QMouseEvent, QCursor,QPixmap
import sys
import json
import os
class CircularButton(QPushButton):
def __init__(self, parent=None):
super().__init__(parent)
self.setFixedSize(100, 100)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint | Qt.Tool)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setStyleSheet("""
CircularButton {
background-color: rgba(1, 160, 196, 50);
border-radius: 50px;
}
QLabel{
color: rgba(255, 255, 255, 100);
font-size: 30px;
font-weight: bold;
text-align: center;
margin-top: 30px;
margin-bottom: 30px;
}
""")
self.text=QLabel(self)
self.text.setText("教材")
self.text.setAlignment(Qt.AlignCenter)
self.text.setGeometry(0, 0, 100, 100)
self.setToolTip("Click to open the main interface")
self.dragging = False
self.drag_position = None
def paintEvent(self, event):
painter = QPainter(self)
painter.setRenderHint(QPainter.Antialiasing)
painter.setBrush(QBrush(QColor(0, 0, 0, 128)))
painter.setPen(Qt.NoPen)
painter.drawEllipse(0, 0, self.width(), self.height())
super().paintEvent(event)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_position = event.pos()
QTimer.singleShot(200, self.check_drag) # Check for dragging after a short delay
super().mousePressEvent(event)
def mouseMoveEvent(self, event):
if event.buttons() == Qt.LeftButton and self.drag_position:
self.dragging = True
self.move(self.mapToParent(event.pos() - self.drag_position))
def mouseReleaseEvent(self, event):
if self.dragging:
self.dragging = False
else:
self.hide()
self.parent().show_rounded_interface(self)
self.drag_position = None
super().mouseReleaseEvent(event)
def check_drag(self):
if self.drag_position:
distance = (self.drag_position - QCursor.pos()).manhattanLength()
if distance > 5:
self.dragging = True
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.setGeometry(300, 300, 300, 550)
self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowStaysOnTopHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.circular_button = CircularButton(self)
self.circular_button.move(250, 150)
self.circular_button.show()
self.rounded_widget = RoundedWidget(self)
self.rounded_widget.hide()
def show_rounded_interface(self, circular_button):
# Move the main window near the circular button
button_pos = circular_button.mapToGlobal(QPoint(0, 0))
old = self.geometry().getRect()
self.setGeometry(button_pos.x() - 250, button_pos.y() - 150, old[2], old[3])
self.rounded_widget.show()
def hide_rounded_interface(self):
self.rounded_widget.hide()
self.circular_button.show()
def mousePressEvent(self, event: QMouseEvent):
if event.button() == Qt.LeftButton:
self.drag_position = event.globalPosition().toPoint()
event.accept()
def mouseMoveEvent(self, event: QMouseEvent):
if event.buttons() & Qt.LeftButton:
self.move(self.pos() + event.globalPosition().toPoint() - self.drag_position)
self.drag_position = event.globalPosition().toPoint()
event.accept()
class RoundedWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setGeometry(50, 50, 200, 450)
self.setWindowFlags(Qt.FramelessWindowHint)
self.setAttribute(Qt.WA_TranslucentBackground)
self.setStyleSheet("""
QPushButton{
background-color: rgba(200, 200, 200, 180);
border-radius: 20px;
}
""")
self.shadow_effect = QGraphicsDropShadowEffect(self)
self.shadow_effect.setBlurRadius(20)
self.shadow_effect.setOffset(0, 0)
self.shadow_effect.setColor(QColor(0, 0, 0, 160))
self.setGraphicsEffect(self.shadow_effect)
self.layout = QVBoxLayout(self)
self.tab_widget = QTabWidget()
self.layout.addWidget(self.tab_widget)
self.close_button = QPushButton("Close", self)
self.close_button.setStyleSheet("font-size: 16px; padding: 10px;")
self.close_button.clicked.connect(self.close)
self.layout.addWidget(self.close_button)
self.close_program_button = QPushButton("Exit Program", self)
self.close_program_button.setStyleSheet("font-size: 16px; padding: 10px;")
self.close_program_button.clicked.connect(self.close_program)
self.layout.addWidget(self.close_program_button)
self.config = self.load_config()
self.create_tabs()
def load_config(self):
with open('config.json', 'r', encoding='utf-8') as file:
return json.load(file)
def create_tabs(self):
for subject, files in self.config.items():
tab = QWidget()
tab_layout = QVBoxLayout(tab)
for title, path in files.items():
button = QPushButton(title)
button.setStyleSheet("font-size: 16px; padding: 10px;")
button.clicked.connect(self.create_button_handler(path))
tab_layout.addWidget(button)
self.tab_widget.addTab(tab, subject)
def create_button_handler(self, path):
return lambda: self.open_file(path)
def open_file(self, path):
os.startfile(path)
def close(self):
self.parent().hide_rounded_interface()
def close_program(self):
QApplication.instance().quit()
if __name__ == "__main__":
app = QApplication(sys.argv)
window = MainWindow()
window.show()
sys.exit(app.exec())

16
textbook/config.json Normal file
View File

@ -0,0 +1,16 @@
{
"化学":{
"化学必修一":"E:/电子教材/化学/普通高中教科书·化学必修 第一册.pdf",
"化学必修二":"E:/电子教材/化学/普通高中教科书·化学必修 第二册.pdf",
"化学选修一":"E:/电子教材/化学/普通高中教科书·化学选择性必修1 化学反应原理.pdf",
"化学选修二":"E:/电子教材/化学/普通高中教科书·化学选择性必修2 物质结构与性质.pdf",
"化学选修三":"E:/电子教材/化学/普通高中教科书·化学选择性必修3 有机化学基础.pdf"
},
"生物":{
"生物必修一":"E:/电子教材/生物/普通高中教科书·生物学必修1 分子与细胞.pdf",
"生物必修二":"E:/电子教材/生物/普通高中教科书·生物学必修2 遗传与进化.pdf",
"生物选修一":"E:/电子教材/生物/普通高中教科书·生物学选择性必修1 稳态与调节.pdf",
"生物选修二":"E:/电子教材/生物/普通高中教科书·生物学选择性必修2 生物与环境.pdf",
"生物选修三":"E:/电子教材/生物/普通高中教科书·生物学选择性必修3 生物技术与工程.pdf"
}
}

BIN
textbook/screen1.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 234 KiB

BIN
textbook/screen2.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 47 KiB