PyQt编写Maya Dockable Window问题汇总

最近在研究用PyQt写Maya插件的界面,遇到不少的疑难杂症,在这里汇总一下,便于日后查询。


与Maya界面融合

首先最主要的目标是想让PyQt写好的界面与Maya完美融合,不会在操作Maya界面的时候把我们自己的窗口压到后面,而网上传统的方法便是使用OpenMayaUI库以及shiboken2库中的wrapInstance方法,将我们的窗口parent到已经存在的Maya窗口中。

官网的Maya开发人员帮助中也给了以下代码示例:

from maya import OpenMayaUI as omui 

from PySide2.QtCore import * 
from PySide2.QtGui import * 
from PySide2.QtWidgets import *
from PySide2 import __version__
from shiboken2 import wrapInstance 

mayaMainWindowPtr = omui.MQtUtil.mainWindow() 
mayaMainWindow= wrapInstance(long(mayaMainWindowPtr), QWidget) 

# WORKS: Widget is fine 
hello = QLabel("Hello, World", parent=mayaMainWindow) 
hello.setObjectName('MyLabel') 
hello.setWindowFlags(Qt.Window) # Make this widget a standalone window even though it is parented 
hello.show() 
hello = None # the "hello" widget is parented, so it will not be destroyed. 

# BROKEN: Widget is destroyed 
hello = QLabel("Hello, World", parent=None) 
hello.setObjectName('MyLabel') 
hello.show() 
hello = None # the "hello" widget is not parented, so it will be destroyed.

代码中对比了parent = mayaMainWindowparent = None两种情况,后者在使用show()方法后窗口会由于Python的GC机制在创建后瞬间消失,但前者由于parent到了Maya的主窗口中,就会由Maya来维持其生命周期。另外,此时在操作Maya界面的时候,我们的窗口也会一直保持置顶不会被挡住。


Dock窗口

为了让我们的窗口能够dock在Maya的UI中,网上常见的方法是结合上面的wrapInstance方法,再通过内置库的cmds.workspaceControl来实现。(注:Maya2017之前的版本为 cmds.dockControl

例如Dhruv Govil大神的Python For Maya: Artist Friendly Programming教程中的一个案例就是如此:

def getDock(name='LightingManagerDock'):
    # Delete existing window first
    deleteDock(name)
    
    ctrl = pm.workspaceControl(name,dockToMainWindow=('right',1),label="Lighting Manager")
    
    qtCtrl = omui.MQtUtil.findControl(ctrl)
    ptr = wrapInstance(long(qtCtrl),QtWidgets.QWidget)
    return ptr

def deleteDock(name='LightingManagerDock'):
    if pm.workspaceControl(name,query=True,exists=True) :
        pm.deleteUI(
### 如何使用 PyQt5 和 QtCharts 绘制折线图 以下是基于 PyQt5 和 QtCharts 模块实现绘制折线图的一个完整示例代码。此代码展示了如何通过 `QChart`、`QChartView` 和 `QLineSeries` 来构建并显示一张简单的折线图。 #### 安装依赖项 由于 `QtCharts` 并不包含在默认的 PyQt5 包中,因此需要单独安装该模块[^2]。可以通过以下命令完成安装: ```bash pip install pyqtchart ``` #### 示例代码 下面提供了一个完整的 Python 脚本,演示如何使用 PyQt5 创建一个窗口并在其中嵌入一条折线图: ```python import sys from PyQt5.QtWidgets import QApplication, QMainWindow from PyQt5.QtCore import QPointF from PyQt5.QtCharts import QChart, QChartView, QLineSeries class MainWindow(QMainWindow): def __init__(self): super().__init__() # 初始化图表对象 chart = QChart() chart.setTitle("Simple Line Chart Example") # 设置图表标题 chart.setAnimationOptions(QChart.SeriesAnimations) # 添加数据系列到图表 series = QLineSeries() # 创建折线序列 points = [(0, 6), (1, 4), (2, 8), (3, 7), (4, 9)] # 数据点列表 for point in points: series.append(point[0], point[1]) # 将数据点加入序列 chart.addSeries(series) # 把序列添加至图表 # 配置坐标轴 chart.createDefaultAxes() # 自动生成默认坐标轴 axis_x = chart.axes(Qt.Horizontal)[0] axis_y = chart.axes(Qt.Vertical)[0] axis_x.setRange(0, max([p[0] for p in points])) # 设定X轴范围 axis_y.setRange(min([p[1] for p in points]), max([p[1] for p in points])) # 设定Y轴范围 # 图表视图设置 chart_view = QChartView(chart) chart_view.setRenderHint(QPainter.Antialiasing) # 开启抗锯齿渲染 self.setCentralWidget(chart_view) # 将图表视图设为主窗口中心部件 self.setWindowTitle("PyQt5 Line Chart Demo") if __name__ == "__main__": app = QApplication(sys.argv) window = MainWindow() window.resize(800, 600) window.show() sys.exit(app.exec_()) ``` 上述代码实现了如下功能: - 使用 `QLineSeries` 类定义了一组二维平面上的数据点,并将其作为折线图的基础[^3]。 - 利用 `QChart` 对象管理整个图表及其内部组件(如坐标轴和图例)。 - 借助 `QChartView` 提供交互式的可视化界面以便用户查看最终效果。 #### 关键技术说明 1. **QLineSeries**: 这是用来表示一系列离散点并将它们连接成线条的核心类。 2. **QChart**: 此类负责统筹所有的绘图元素以及控制整体布局与样式。 3. **QChartView**: 是一种专门用来呈现由 `QChart` 所描述的内容的小部件。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值