在 **3D Slicer** 中嵌入前端静态页面可以通过 **Qt WebEngine** 实现。3D Slicer 基于 Qt 框架,而 Qt 提供了 `QWebEngineView` 组件,能够嵌入浏览器功能并加载静态页面(如 HTML、CSS、JavaScript 文件)。
以下是详细的实现步骤和示例代码:
---
### **1. 准备工作**
确保你的 3D Slicer 版本支持 **Qt WebEngine**(通常需要 3D Slicer 5.0 及以上版本)。如果支持,可以直接在 Python 脚本中使用 `QWebEngineView`。
---
### **2. 嵌入静态页面**
#### **2.1 创建静态页面**
首先,准备一个静态页面(HTML 文件)。例如,创建一个名为 `index.html` 的文件:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Slicer Static Page</title>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
text-align: center;
padding: 50px;
}
h1 {
color: #333;
}
</style>
</head>
<body>
<h1>Hello from 3D Slicer!</h1>
<p>This is a static page embedded in 3D Slicer.</p>
</body>
</html>
```
将 `index.html` 文件保存到本地,例如 `C:/path/to/index.html`。
---
#### **2.2 在 3D Slicer 中嵌入页面**
使用 `QWebEngineView` 加载并显示静态页面。
```python
from qtpy.QtWidgets import QVBoxLayout, QWidget
from qtpy.QtWebEngineWidgets import QWebEngineView
import slicer
class WebViewWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUI()
def setupUI(self):
self.layout = QVBoxLayout(self)
# 创建浏览器组件
self.browser = QWebEngineView()
self.layout.addWidget(self.browser)
# 加载本地静态页面
self.browser.setUrl("file:///C:/path/to/index.html") # 替换为你的 HTML 文件路径
# 将浏览器组件添加到 3D Slicer 界面中
web_widget = WebViewWidget()
slicer.app.layoutManager().layout().addWidget(web_widget)
```
---
### **3. 支持 JavaScript 交互**
如果静态页面中包含 JavaScript 代码,可以通过 `QWebEngineView` 实现与 3D Slicer 的交互。
#### **3.1 从页面调用 Python 函数**
通过 `QWebChannel`,可以将 Python 对象暴露给页面的 JavaScript 代码。
1. **修改 HTML 文件**:
在 `index.html` 中添加 JavaScript 代码:
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>3D Slicer Static Page</title>
<script src="qrc:///qtwebchannel/qwebchannel.js"></script>
<style>
body {
font-family: Arial, sans-serif;
background-color: #f0f0f0;
text-align: center;
padding: 50px;
}
h1 {
color: #333;
}
button {
padding: 10px 20px;
font-size: 16px;
margin-top: 20px;
}
</style>
</head>
<body>
<h1>Hello from 3D Slicer!</h1>
<p>This is a static page embedded in 3D Slicer.</p>
<button onclick="callPythonFunction()">Call Python Function</button>
<script>
// 初始化 QWebChannel
new QWebChannel(qt.webChannelTransport, function (channel) {
window.pythonHandler = channel.objects.pythonHandler;
});
// 调用 Python 函数
function callPythonFunction() {
if (window.pythonHandler) {
pythonHandler.handleButtonClick("Button clicked!");
} else {
console.error("Python handler not found.");
}
}
</script>
</body>
</html>
```
2. **修改 Python 代码**:
在 Python 中实现 `QWebChannel` 的交互逻辑:
```python
from qtpy.QtCore import QObject, Slot
from qtpy.QtWebChannel import QWebChannel
from qtpy.QtWidgets import QVBoxLayout, QWidget
from qtpy.QtWebEngineWidgets import QWebEngineView
import slicer
class PythonHandler(QObject):
@Slot(str)
def handleButtonClick(self, message):
print("Received from JavaScript:", message)
class WebViewWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.setupUI()
def setupUI(self):
self.layout = QVBoxLayout(self)
# 创建浏览器组件
self.browser = QWebEngineView()
self.layout.addWidget(self.browser)
# 设置 WebChannel
self.channel = QWebChannel()
self.handler = PythonHandler()
self.channel.registerObject("pythonHandler", self.handler)
self.browser.page().setWebChannel(self.channel)
# 加载本地静态页面
self.browser.setUrl("file:///C:/path/to/index.html") # 替换为你的 HTML 文件路径
# 将浏览器组件添加到 3D Slicer 界面中
web_widget = WebViewWidget()
slicer.app.layoutManager().layout().addWidget(web_widget)
```
---
### **4. 总结**
- **嵌入静态页面**:使用 `QWebEngineView` 加载本地 HTML 文件。
- **支持 JavaScript 交互**:通过 `QWebChannel` 实现 Python 与 JavaScript 的双向通信。
- **适用场景**:
- 在 3D Slicer 中显示自定义的用户界面。
- 实现复杂的交互逻辑(如按钮点击、数据传递等)。