mayamaya-api

Set highlighted range in Maya's Time Slider


It is easy to get the highligted range in the time slider using:

import maya.cmds as cmds
import maya.mel as mel

aTimeSlider = mel.eval('$tmpVar=$gPlayBackSlider')
timeRange = cmds.timeControl(aTimeSlider, q=True, rangeArray=True)

Likewise the Qt widget can be accessed with

from maya import mel
from maya import OpenMayaUI as omui 

try:
  from PySide2.QtCore import * 
  from PySide2.QtGui import * 
  from PySide2.QtWidgets import *
  from PySide2 import __version__
  from shiboken2 import wrapInstance 
except ImportError:
  from PySide.QtCore import * 
  from PySide.QtGui import * 
  from PySide import __version__
  from shiboken import wrapInstance 

widgetStr = mel.eval( 'string $tempString = $gPlayBackSlider' )    
ptr = omui.MQtUtil.findControl( widgetStr )
timeSliderWidget = wrapInstance(long(ptr), QWidget)

However, setting the highlighted range programmatically of the time slider seems nearly impossible. Is there really no way?

I was thinking that there may be a way to modify the Qt widget, but I'm lost on this one.

EDIT:

It is the highlighted range I'm trying to set programmatically. Maya Time Slider highlighted range


Solution

  • This seems to be the same question as this question.

    I posted a hacky workaround there as an answer.

    Posting it here too for completeness sake: Here's the biggest hacky workaround there is. Using Qt Mouse press, move and release events to mimic the mouse behavior on the time slider widget to have it select.

    In code I'm temporarily changing the time slider range to maximize the screen space for the frames I want to click on.

    from maya import mel
    from maya import OpenMayaUI as omui 
    
    from shiboken2 import wrapInstance 
    from PySide2 import QtCore, QtGui, QtWidgets
    
    
    def select_time_slider_range(start, end):
        
        app = QtWidgets.QApplication.instance()
        
        widgetStr = mel.eval('$gPlayBackSlider=$gPlayBackSlider')
        ptr = omui.MQtUtil.findControl(widgetStr)
        slider = wrapInstance(long(ptr), QtWidgets.QWidget)
        
        slider_width = slider.size().width()
        slider_height = slider.size().height()
        
        # Store time slider settings
        min_time = cmds.playbackOptions(query=True, minTime=True)
        max_time = cmds.playbackOptions(query=True, maxTime=True)
        animation_start_time = cmds.playbackOptions(query=True, animationStartTime=True)
        animation_end_time = cmds.playbackOptions(query=True, animationEndTime=True)
        t = cmds.currentTime(query=True)
        
        # Set the time slider to the range we want so we have
        # perfect precision to click at the start and end of the
        # time slider.
        cmds.playbackOptions(minTime=start)
        cmds.playbackOptions(maxTime=end)
        
        a_pos = QtCore.QPoint(0, slider_height / 2.0)         
        b_pos = QtCore.QPoint(slider_width, slider_height / 2.0)
        
        # Trigger some mouse events on the Time Control
        # Somehow we need to have some move events around
        # it so the UI correctly understands it stopped
        # clicking, etc.
        event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, 
                                  a_pos, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.NoModifier)
        app.sendEvent(slider, event)
        
        event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonPress, 
                                  a_pos, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.ShiftModifier)
        app.sendEvent(slider, event)
       
        event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, 
                                  b_pos, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.ShiftModifier)
        app.sendEvent(slider, event)
    
        event = QtGui.QMouseEvent(QtCore.QEvent.MouseButtonRelease, 
                                  b_pos, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.ShiftModifier)
        app.sendEvent(slider, event)
        
        event = QtGui.QMouseEvent(QtCore.QEvent.MouseMove, 
                                  b_pos, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.MouseButton.LeftButton, 
                                  QtCore.Qt.NoModifier)
        app.sendEvent(slider, event)
        app.processEvents()
        
        # Reset time slider settings
        cmds.playbackOptions(minTime=min_time)
        cmds.playbackOptions(maxTime=max_time)
        cmds.playbackOptions(animationStartTime=animation_start_time)
        cmds.playbackOptions(animationEndTime=animation_end_time)
        cmds.currentTime(t)
    
    select_time_slider_range(-200, 500000)