Example:
Created
June 23, 2021 08:32
-
-
Save davidlatwe/b6dbc5144b360f51eddb8443705b5e1e to your computer and use it in GitHub Desktop.
Qt widget: Page sliding
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import os | |
import sys | |
from Qt5 import QtCore, QtWidgets | |
from . import widgets | |
class Foo(QtWidgets.QWidget): | |
bar_clicked = QtCore.Signal() | |
def __init__(self, parent=None): | |
super(Foo, self).__init__(parent=parent) | |
btn = QtWidgets.QPushButton("Bar") | |
btn.clicked.connect(self.bar_clicked.emit) | |
layout = QtWidgets.QVBoxLayout(self) | |
layout.addWidget(btn) | |
class Bar(QtWidgets.QWidget): | |
foo_clicked = QtCore.Signal() | |
def __init__(self, parent=None): | |
super(Bar, self).__init__(parent=parent) | |
btn = QtWidgets.QPushButton("Foo") | |
btn.clicked.connect(self.foo_clicked.emit) | |
layout = QtWidgets.QVBoxLayout(self) | |
layout.addWidget(btn) | |
class Window(QtWidgets.QWidget): | |
def __init__(self, parent=None): | |
super(Window, self).__init__(parent=parent) | |
foo = view.Foo() | |
bar = view.Bar() | |
slider = widgets.SlidePageWidget() | |
slider.addWidget(foo) | |
slider.addWidget(bar) | |
foo.bar_clicked.connect(lambda: self.set_page(1)) | |
bar.foo_clicked.connect(lambda: self.set_page(0)) | |
layout = QtWidgets.QVBoxLayout(self) | |
layout.addWidget(slider) | |
self.slider = slider | |
self._page = 0 | |
def set_page(self, page): | |
current = self.slider.currentIndex() | |
if current == page and self._page == page: | |
return | |
direction = "right" if page > current else "left" | |
self._page = page | |
self.slider.slide_view(page, direction=direction) | |
def init(): | |
if sys.platform == "darwin": | |
os.environ["QT_MAC_WANTS_LAYER"] = "1" # MacOS BigSur | |
qapp = QtWidgets.QApplication.instance() or QtWidgets.QApplication([]) | |
window = Window() | |
return qapp, window | |
def main(): | |
qapp, window = init() | |
window.show() | |
return qapp.exec_() |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
from Qt5 import QtCore, QtWidgets | |
class SlidePageWidget(QtWidgets.QStackedWidget): | |
"""Stacked widget that nicely slides between its pages""" | |
directions = { | |
"left": QtCore.QPoint(-1, 0), | |
"right": QtCore.QPoint(1, 0), | |
"up": QtCore.QPoint(0, 1), | |
"down": QtCore.QPoint(0, -1) | |
} | |
def slide_view(self, index, direction="right"): | |
if self.currentIndex() == index: | |
return | |
offset_direction = self.directions.get(direction) | |
if offset_direction is None: | |
print("BUG: invalid slide direction: {}".format(direction)) | |
return | |
width = self.frameRect().width() | |
height = self.frameRect().height() | |
offset = QtCore.QPoint( | |
offset_direction.x() * width, | |
offset_direction.y() * height | |
) | |
new_page = self.widget(index) | |
new_page.setGeometry(0, 0, width, height) | |
curr_pos = new_page.pos() | |
new_page.move(curr_pos + offset) | |
new_page.show() | |
new_page.raise_() | |
current_page = self.currentWidget() | |
b_pos = QtCore.QByteArray(b"pos") | |
anim_old = QtCore.QPropertyAnimation(current_page, b_pos, self) | |
anim_old.setDuration(250) | |
anim_old.setStartValue(curr_pos) | |
anim_old.setEndValue(curr_pos - offset) | |
anim_old.setEasingCurve(QtCore.QEasingCurve.OutQuad) | |
anim_new = QtCore.QPropertyAnimation(new_page, b_pos, self) | |
anim_new.setDuration(250) | |
anim_new.setStartValue(curr_pos + offset) | |
anim_new.setEndValue(curr_pos) | |
anim_new.setEasingCurve(QtCore.QEasingCurve.OutQuad) | |
anim_group = QtCore.QParallelAnimationGroup(self) | |
anim_group.addAnimation(anim_old) | |
anim_group.addAnimation(anim_new) | |
def slide_finished(): | |
self.setCurrentWidget(new_page) | |
anim_group.finished.connect(slide_finished) | |
anim_group.start() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment