332 lines
12 KiB
Python
332 lines
12 KiB
Python
# OPCIÓN 1: PySide6 (RECOMENDADA)
|
||
# pip install PySide6
|
||
|
||
import sys
|
||
from PySide6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget, QPushButton, QHBoxLayout
|
||
from PySide6.QtWebEngineWidgets import QWebEngineView
|
||
from PySide6.QtCore import QUrl
|
||
|
||
class MathJaxPySide6(QMainWindow):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.setWindowTitle("🧮 MathJax con PySide6")
|
||
self.setGeometry(100, 100, 1200, 800)
|
||
|
||
# Widget central
|
||
central_widget = QWidget()
|
||
self.setCentralWidget(central_widget)
|
||
|
||
# Layout principal
|
||
layout = QVBoxLayout(central_widget)
|
||
|
||
# Botones de control
|
||
button_layout = QHBoxLayout()
|
||
|
||
btn_reload = QPushButton("🔄 Recargar")
|
||
btn_zoom_in = QPushButton("🔍+ Zoom In")
|
||
btn_zoom_out = QPushButton("🔍- Zoom Out")
|
||
btn_fullscreen = QPushButton("📺 Pantalla Completa")
|
||
|
||
btn_reload.clicked.connect(self.reload_page)
|
||
btn_zoom_in.clicked.connect(self.zoom_in)
|
||
btn_zoom_out.clicked.connect(self.zoom_out)
|
||
btn_fullscreen.clicked.connect(self.toggle_fullscreen)
|
||
|
||
button_layout.addWidget(btn_reload)
|
||
button_layout.addWidget(btn_zoom_in)
|
||
button_layout.addWidget(btn_zoom_out)
|
||
button_layout.addWidget(btn_fullscreen)
|
||
button_layout.addStretch()
|
||
|
||
layout.addLayout(button_layout)
|
||
|
||
# Vista web
|
||
self.web_view = QWebEngineView()
|
||
layout.addWidget(self.web_view)
|
||
|
||
# HTML con MathJax avanzado
|
||
self.html_content = """
|
||
<!DOCTYPE html>
|
||
<html lang="es">
|
||
<head>
|
||
<meta charset="UTF-8">
|
||
<title>MathJax Avanzado</title>
|
||
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
|
||
<script id="MathJax-script" async src="https://cdn.jsdelivr.net/npm/mathjax@3/es5/tex-chtml.js"></script>
|
||
<script>
|
||
MathJax = {
|
||
tex: {
|
||
inlineMath: [['$', '$'], ['\\\\(', '\\\\)']],
|
||
displayMath: [['$$', '$$'], ['\\\\[', '\\\\]']],
|
||
packages: {'[+]': ['ams', 'color', 'physics']}
|
||
},
|
||
chtml: {
|
||
scale: 1.3,
|
||
minScale: 0.5,
|
||
matchFontHeight: false
|
||
}
|
||
};
|
||
</script>
|
||
<style>
|
||
body {
|
||
font-family: 'Segoe UI', sans-serif;
|
||
margin: 30px;
|
||
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
|
||
min-height: 100vh;
|
||
}
|
||
.container {
|
||
background: white;
|
||
border-radius: 15px;
|
||
padding: 40px;
|
||
box-shadow: 0 20px 40px rgba(0,0,0,0.1);
|
||
max-width: 1000px;
|
||
margin: 0 auto;
|
||
}
|
||
h1 { color: #2c3e50; text-align: center; margin-bottom: 40px; }
|
||
.section {
|
||
background: #f8f9fa;
|
||
border-left: 5px solid #007bff;
|
||
padding: 25px;
|
||
margin: 25px 0;
|
||
border-radius: 0 10px 10px 0;
|
||
box-shadow: 0 5px 15px rgba(0,0,0,0.08);
|
||
}
|
||
.section h3 {
|
||
color: #495057;
|
||
margin-top: 0;
|
||
margin-bottom: 15px;
|
||
}
|
||
.interactive {
|
||
background: #e8f5e8;
|
||
border-left-color: #28a745;
|
||
}
|
||
.physics {
|
||
background: #fff3cd;
|
||
border-left-color: #ffc107;
|
||
}
|
||
.advanced {
|
||
background: #f8d7da;
|
||
border-left-color: #dc3545;
|
||
}
|
||
button {
|
||
background: #007bff;
|
||
color: white;
|
||
border: none;
|
||
padding: 12px 24px;
|
||
border-radius: 6px;
|
||
cursor: pointer;
|
||
margin: 8px;
|
||
font-size: 14px;
|
||
transition: all 0.3s;
|
||
}
|
||
button:hover {
|
||
background: #0056b3;
|
||
transform: translateY(-2px);
|
||
}
|
||
#dynamic-content {
|
||
margin-top: 20px;
|
||
min-height: 100px;
|
||
}
|
||
</style>
|
||
</head>
|
||
<body>
|
||
<div class="container">
|
||
<h1>🚀 Laboratorio Matemático Avanzado</h1>
|
||
|
||
<div class="section">
|
||
<h3>📊 Álgebra Lineal</h3>
|
||
<p>Determinante de matriz 3×3:</p>
|
||
$$\\det(A) = \\begin{vmatrix}
|
||
a_{11} & a_{12} & a_{13} \\\\
|
||
a_{21} & a_{22} & a_{23} \\\\
|
||
a_{31} & a_{32} & a_{33}
|
||
\\end{vmatrix}$$
|
||
|
||
<p>Eigenvalores: $\\det(A - \\lambda I) = 0$</p>
|
||
</div>
|
||
|
||
<div class="section physics">
|
||
<h3>⚛️ Física Cuántica</h3>
|
||
<p>Operador Hamiltoniano:</p>
|
||
$$\\hat{H} = \\frac{-\\hbar^2}{2m}\\nabla^2 + V(\\mathbf{r})$$
|
||
|
||
<p>Función de onda normalizada:</p>
|
||
$$\\int_{-\\infty}^{\\infty} |\\Psi(x,t)|^2 dx = 1$$
|
||
</div>
|
||
|
||
<div class="section advanced">
|
||
<h3>🔬 Matemáticas Avanzadas</h3>
|
||
<p>Transformada de Fourier:</p>
|
||
$$\\mathcal{F}[f(t)] = \\int_{-\\infty}^{\\infty} f(t) e^{-2\\pi i \\xi t} dt$$
|
||
|
||
<p>Función Gamma:</p>
|
||
$$\\Gamma(z) = \\int_0^\\infty t^{z-1} e^{-t} dt$$
|
||
</div>
|
||
|
||
<div class="section interactive">
|
||
<h3>🎮 Generador Interactivo</h3>
|
||
<button onclick="addCalculusExample()">📈 Cálculo</button>
|
||
<button onclick="addStatisticsExample()">📊 Estadística</button>
|
||
<button onclick="addGeometryExample()">📐 Geometría</button>
|
||
<button onclick="addPhysicsExample()">⚛️ Física</button>
|
||
<button onclick="clearContent()">🧹 Limpiar</button>
|
||
|
||
<div id="dynamic-content"></div>
|
||
</div>
|
||
</div>
|
||
|
||
<script>
|
||
const examples = {
|
||
calculus: [
|
||
{
|
||
title: "Regla de L'Hôpital",
|
||
eq: "$$\\\\lim_{x \\\\to c} \\\\frac{f(x)}{g(x)} = \\\\lim_{x \\\\to c} \\\\frac{f'(x)}{g'(x)}$$"
|
||
},
|
||
{
|
||
title: "Integración por partes",
|
||
eq: "$$\\\\int u \\\\, dv = uv - \\\\int v \\\\, du$$"
|
||
}
|
||
],
|
||
statistics: [
|
||
{
|
||
title: "Distribución Normal",
|
||
eq: "$$f(x) = \\\\frac{1}{\\\\sigma\\\\sqrt{2\\\\pi}} e^{-\\\\frac{(x-\\\\mu)^2}{2\\\\sigma^2}}$$"
|
||
},
|
||
{
|
||
title: "Teorema Central del Límite",
|
||
eq: "$$\\\\bar{X}_n \\\\xrightarrow{d} \\\\mathcal{N}\\\\left(\\\\mu, \\\\frac{\\\\sigma^2}{n}\\\\right)$$"
|
||
}
|
||
],
|
||
geometry: [
|
||
{
|
||
title: "Volumen de esfera",
|
||
eq: "$$V = \\\\frac{4}{3}\\\\pi r^3$$"
|
||
},
|
||
{
|
||
title: "Ley de cosenos",
|
||
eq: "$$c^2 = a^2 + b^2 - 2ab\\\\cos(C)$$"
|
||
}
|
||
],
|
||
physics: [
|
||
{
|
||
title: "Ecuaciones de Maxwell",
|
||
eq: "$$\\\\nabla \\\\cdot \\\\mathbf{E} = \\\\frac{\\\\rho}{\\\\epsilon_0}$$"
|
||
},
|
||
{
|
||
title: "Relatividad Especial",
|
||
eq: "$$t' = \\\\gamma \\\\left(t - \\\\frac{vx}{c^2}\\\\right)$$"
|
||
}
|
||
]
|
||
};
|
||
|
||
function addExample(category) {
|
||
const categoryExamples = examples[category];
|
||
const randomExample = categoryExamples[Math.floor(Math.random() * categoryExamples.length)];
|
||
|
||
const content = document.getElementById('dynamic-content');
|
||
const div = document.createElement('div');
|
||
div.className = 'section';
|
||
div.innerHTML = `
|
||
<h4>➕ ${randomExample.title}</h4>
|
||
${randomExample.eq}
|
||
`;
|
||
content.appendChild(div);
|
||
|
||
MathJax.typesetPromise([div]);
|
||
}
|
||
|
||
function addCalculusExample() { addExample('calculus'); }
|
||
function addStatisticsExample() { addExample('statistics'); }
|
||
function addGeometryExample() { addExample('geometry'); }
|
||
function addPhysicsExample() { addExample('physics'); }
|
||
|
||
function clearContent() {
|
||
document.getElementById('dynamic-content').innerHTML = '';
|
||
}
|
||
|
||
MathJax.startup.promise.then(() => {
|
||
console.log('✅ MathJax cargado en PySide6!');
|
||
});
|
||
</script>
|
||
</body>
|
||
</html>
|
||
"""
|
||
|
||
# Cargar contenido
|
||
self.web_view.setHtml(self.html_content)
|
||
|
||
def reload_page(self):
|
||
self.web_view.setHtml(self.html_content)
|
||
|
||
def zoom_in(self):
|
||
current_zoom = self.web_view.zoomFactor()
|
||
self.web_view.setZoomFactor(current_zoom * 1.2)
|
||
|
||
def zoom_out(self):
|
||
current_zoom = self.web_view.zoomFactor()
|
||
self.web_view.setZoomFactor(current_zoom / 1.2)
|
||
|
||
def toggle_fullscreen(self):
|
||
if self.isFullScreen():
|
||
self.showNormal()
|
||
else:
|
||
self.showFullScreen()
|
||
|
||
# OPCIÓN 2: PyQt6 (Alternativa)
|
||
# pip install PyQt6 PyQt6-WebEngine
|
||
|
||
"""
|
||
import sys
|
||
from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QWidget
|
||
from PyQt6.QtWebEngineWidgets import QWebEngineView
|
||
|
||
class MathJaxPyQt6(QMainWindow):
|
||
def __init__(self):
|
||
super().__init__()
|
||
self.setWindowTitle("MathJax con PyQt6")
|
||
self.setGeometry(100, 100, 1000, 700)
|
||
|
||
central_widget = QWidget()
|
||
self.setCentralWidget(central_widget)
|
||
layout = QVBoxLayout(central_widget)
|
||
|
||
self.web_view = QWebEngineView()
|
||
layout.addWidget(self.web_view)
|
||
|
||
# Mismo HTML que PySide6
|
||
html_content = "[MISMO HTML DE ARRIBA]"
|
||
self.web_view.setHtml(html_content)
|
||
|
||
def run_pyqt6():
|
||
app = QApplication(sys.argv)
|
||
window = MathJaxPyQt6()
|
||
window.show()
|
||
sys.exit(app.exec())
|
||
"""
|
||
|
||
def run_pyside6():
|
||
app = QApplication(sys.argv)
|
||
window = MathJaxPySide6()
|
||
window.show()
|
||
sys.exit(app.exec())
|
||
|
||
if __name__ == "__main__":
|
||
print("🧮 Iniciando aplicación MathJax con PySide6...")
|
||
print("✨ Funciones disponibles:")
|
||
print(" - Zoom in/out")
|
||
print(" - Pantalla completa")
|
||
print(" - Generador interactivo de ecuaciones")
|
||
print(" - MathJax completamente funcional")
|
||
|
||
run_pyside6()
|
||
|
||
# RESUMEN DE INSTALACIÓN:
|
||
#
|
||
# Para PySide6 (RECOMENDADO):
|
||
# pip install PySide6
|
||
#
|
||
# Para PyQt6:
|
||
# pip install PyQt6 PyQt6-WebEngine
|
||
#
|
||
# Ambos funcionan igual de bien para MathJax,
|
||
# pero PySide6 tiene licencia más permisiva. |