textbook
This commit is contained in:
67
textbook/README.md
Normal file
67
textbook/README.md
Normal 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` 相同的目录下。
|
||||
|
||||
## 示例截图
|
||||
|
||||

|
||||

|
173
textbook/app_1.py
Normal file
173
textbook/app_1.py
Normal 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
16
textbook/config.json
Normal 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
BIN
textbook/screen1.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 234 KiB |
BIN
textbook/screen2.png
Normal file
BIN
textbook/screen2.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 47 KiB |
Reference in New Issue
Block a user