Ipywidgets cut off or zero height

I’m working on this PR [ENH, MAINT] Refactor pyvistaqt/notebook widgets abstraction by alexrockhill · Pull Request #10803 · mne-tools/mne-python · GitHub trying to make an abstraction that will work for both pyvistaqt and notebook widgets. To run the example you’d have to do pip install pyvistaqt, pip install git+https://github.com/alexrockhill/mne-python.git@window2.

This code nearly replicates the second block of code making a GUI in qt but some of the widgets are disappearing when there are too many, does anyone have a few minutes to advise? Thanks so much in advance!

Notebook:

%matplotlib widget
import mne
import matplotlib.pyplot as plt
mne.viz.set_3d_backend('notebook')
from ipywidgets import Output
import threading
from mne.viz.backends.renderer import backend
window = backend._Window()
central_layout = backend._VBoxLayout(scroll=(400, 400))
canvas = backend._MplCanvas(2, 2, 96)
canvas.ax.plot(range(10), range(10), label='plot')
central_layout._add_widget(canvas)
central_layout._add_widget(backend._Label('test'))
central_layout._add_widget(
    backend._Text('test', 'placeholder', lambda x: print(x)))
central_layout._add_widget(
    backend._Button('test2', callback=lambda: print('test3')))
central_layout._add_widget(
    backend._FileButton(lambda name: print(name), window=window))
slider = backend._Slider(0, (0, 100), lambda x: print(x))
central_layout._add_widget(slider)
central_layout._add_widget(
    backend._CheckBox(0, lambda x: print(x)))
central_layout._add_widget(
    backend._SpinBox(10, (5, 50), lambda x: print(x), step=4))
central_layout._add_widget(
    backend._ComboBox('40', ('5', '50', '40'), lambda x: print(x)))
central_layout._add_widget(
    backend._RadioButtons('40', ('5', '50', '40'), lambda x: print(x)))
gb = backend._GroupBox('menu', [backend._Button(
    f'{i}', callback=lambda: print('test3')) for i in range(5)])
gb._set_enabled(False)
central_layout._add_widget(gb)
# need out just for printing to terminal because of the play
# button to slider link
out = Output()
def play_callback(x):
    with out:
        print(x)
play_menu = backend._PlayMenu(0, (0, 100), play_callback)
central_layout._add_widget(play_menu)
central_layout._add_widget(out)
pb = backend._ProgressBar(100)

def update_pb():
    pb._update()
    threading.Timer(0.25, update_pb).start()
    
update_pb()
central_layout._add_widget(pb)
out = Output()
def key_callback(x):
    with out:
        print(x)
window._add_keypress(key_callback)
window._set_central_layout(central_layout)
window._set_focus()
window._show()
#dialog = backend._Dialog('Info', 'this is a message', 'test',
#                         lambda x: print(x), window=window)

Qt:

import mne
from qtpy.QtCore import QTimer
from matplotlib.backends.backend_qt5agg import FigureCanvas
from matplotlib.figure import Figure
mne.viz.set_3d_backend('pyvistaqt')
app = mne.viz.backends._utils._init_mne_qtapp()
from mne.viz.backends.renderer import backend
window = backend._Window()
central_layout = backend._VBoxLayout(scroll=(500, 500))
canvas = backend._MplCanvas(5, 5, 96)
canvas.ax.plot(range(10), range(10), label='plot')
central_layout._add_widget(canvas)
central_layout._add_widget(backend._Label('test'))
central_layout._add_widget(backend._Text('test', 'placeholder', lambda x: print(x)))
button = backend._Button('test2', callback=lambda: print('test3'))
central_layout._add_widget(button)
slider = backend._Slider(0, (0, 100), lambda x: print(x))
central_layout._add_widget(slider)
central_layout._add_widget(backend._CheckBox(0, lambda x: print(x)))
central_layout._add_widget(backend._SpinBox(10, (5, 50), lambda x: print(x), step=4))
central_layout._add_widget(backend._ComboBox('40', ('5', '50', '40'), lambda x: print(x)))
buttons = backend._RadioButtons('40', ('5', '50', '40'), lambda x: print(x))
central_layout._add_widget(buttons)
gb = backend._GroupBox('menu', [backend._Button(f'{i}', callback=lambda: print('test3')) for i in range(5)])
gb._set_enabled(False)
central_layout._add_widget(gb)
central_layout._add_widget(backend._FileButton(lambda name: print(name), window=window))
play_menu = backend._PlayMenu(0, (0, 100), lambda x: print(x))
central_layout._add_widget(play_menu)
pb = backend._ProgressBar(100)
timer = QTimer()
timer.timeout.connect(pb._update)
timer.setInterval(250)
timer.start()
central_layout._add_widget(pb)
window._add_keypress(lambda x: print(x))
window._set_central_layout(central_layout)
window._set_focus()
window._show()
# pop up
#dialog = backend._Dialog('Info', 'this is a message', 'test', lambda x: print(x))

app.exec_()

Ah, for some reason, setting the min_width/height of the layout does wonders for making things fill up the space appropriately following the guideline under the carousel example here Layout and Styling of Jupyter widgets — Jupyter Widgets 8.0.0rc0 documentation. Not completely sure how that all works with the css translation but fixes my issue.