コード例 #1
0
ファイル: RoboKitty.py プロジェクト: neoxharsh/RoboKitty
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.config = Config()
        self.setWindowFlag(QtCore.Qt.FramelessWindowHint)
        self.tabWidget = QTabWidget()
        self._mainLayout = QVBoxLayout()
        self._topBar = QHBoxLayout()
        self.windowCloseButton = QPushButton()
        self.windowCloseButton.setText("X")
        self.windowCloseButton.setFixedWidth(25)
        self.windowCloseButton.setFixedHeight(25)
        self.windowCloseButton.clicked.connect(lambda: self.close())
        self._windowMoveLine = QFrame()
        self._windowMoveLine.setFrameShadow(QFrame.Plain)
        self._windowMoveLine.setStyleSheet("background: black;")
        self._windowMoveLine.setFrameShape(QFrame.HLine)
        self._windowMoveLine.setMinimumSize(10, 10)
        self._topBar.addWidget(self._windowMoveLine)
        self._topBar.addWidget((self.windowCloseButton))
        self._mainLayout.addLayout(self._topBar)
        self._mainLayout.addWidget(self.tabWidget)
        self.setLayout(self._mainLayout)
        self._windowMoveLine.mousePressEvent = self.windowBarMove
        self._windowMoveLine.mouseMoveEvent = self.windowBarMove

        try:
            self.config = pickle.load(open('config.pkl', 'rb'))

        except:
            print("error opening Config File")
        self.isRoboKittyConnected = False
        self.areMotorsEnabled = False

        self.RearRightShoulder = None  # type:AX12A
        self.RearRightFemur = None  # type:AX12A
        self.RearRightLeg = None  # type:AX12A

        self.RearLeftShoulder = None  # type:AX12A
        self.RearLeftFemur = None  # type:AX12A
        self.RearLeftLeg = None  # type:AX12A

        self.FrontLeftShoulder = None  # type:AX12A
        self.FrontLeftFemur = None  # type:AX12A
        self.FrontLeftLeg = None  # type:AX12A

        self.FrontRightShoulder = None  # type:AX12A
        self.FrontRightFemur = None  # type:AX12A
        self.FrontRightLeg = None  # type:AX12A

        self.ax12aInstances = []
        AX12A.debugEnabled = False
        sizeGrip = QSizeGrip(self)
        sizeGrip.setVisible(True)
        self._mainLayout.addWidget(
            sizeGrip, 0, QtCore.Qt.AlignBottom | QtCore.Qt.AlignRight)
        self.setupUi(self.tabWidget)

        self.tabWidget.setCurrentIndex(1)
        self.init()
コード例 #2
0
    def __init__(self):
        QMainWindow.__init__(self)
        self.ui = MainUI()
        self.ui.setupUi(self)
        self.setWindowFlags(Qt.FramelessWindowHint | Qt.WindowMinimizeButtonHint)
        self.gripSize = 16
        self.grips = []
        # Resize window
        for i in range(4):
            grip = QSizeGrip(self)
            grip.setVisible(False)
            grip.resize(self.gripSize, self.gripSize)
            self.grips.append(grip)

        self._btn_clicked_connect()
        self.show()
コード例 #3
0
 def __init__(self):
     super().__init__()
     self.title = "PyQt5 Size Grip"
     self.top = 200
     self.left = 500
     self.width = 640
     self.height = 480
     self.setWindowTitle(self.title)
     self.setWindowIcon(QtGui.QIcon("avatar.png"))
     self.setGeometry(self.left, self.top, self.width, self.height)
     flags = QtCore.Qt.WindowFlags(QtCore.Qt.FramelessWindowHint
                                   | QtCore.Qt.WindowStaysOnTopHint)
     self.setWindowFlags(flags)
     vboxlayout = QVBoxLayout()
     sizegrip = QSizeGrip(self)
     sizegrip.setVisible(True)
     vboxlayout.addWidget(sizegrip)
     self.setLayout(vboxlayout)
     self.show()
コード例 #4
0
    def __init__(self, parent, url, image_size):
        super().__init__()
        self.main = parent
        self.setupUi(self)
        self.setAcceptDrops(True)
        self.url = url
        self.image = QImage(url)
        self.image_size = image_size
        self.setBackgroundExists()
        self.resized.connect(self.synchronize)

        flags = QtCore.Qt.WindowFlags(QtCore.Qt.FramelessWindowHint | QtCore.Qt.WindowStaysOnTopHint)
        self.setWindowFlags(flags)
        sizegrip = QSizeGrip(self)
        sizegrip.setVisible(True)
        self.gridLayout.addWidget(sizegrip)

        self.pushButton_close.clicked.connect(self.on_click)
        self.pushButton_cancel.clicked.connect(self.on_click)
        self.pushbutton_calibrate.clicked.connect(self.on_click)
        self.title.installEventFilter(self)
        self.pressing = False
コード例 #5
0
ファイル: Notepad+.py プロジェクト: yashrajput0508/Notepad-
    def status(self):
        if self.statused.isChecked() == True:
            self.statusbar = QStatusBar(self)
            self.statusbar.setGeometry(
                QRect(self.geometry().x() - self.geometry().getCoords()[0],
                      self.geometry().width(),
                      self.geometry().width(), 20))
            self.textEdit.setGeometry(
                QRect(self.geometry().x() - self.geometry().getCoords()[0],
                      self.geometry().y() - self.geometry().getCoords()[1],
                      self.geometry().width(),
                      self.geometry().height() - 42))
            font = QFont()
            font.setPointSize(10)
            self.statusbar.setFont(font)
            self.label = QLabel("Row: 0 | Col: 0")
            self.statusbar.addPermanentWidget(self.label)
            self.time = QLCDNumber()
            self.time.setDigitCount(8)
            self.time.setFrameShadow(QFrame.Sunken)
            self.time.setFrameShape(QFrame.Panel)
            self.statusbar.addWidget(self.time)
            self.setStatusBar(self.statusbar)
        else:
            self.textEdit.setGeometry(
                QRect(self.geometry().x() - self.geometry().getCoords()[0],
                      self.geometry().y() - self.geometry().getCoords()[1],
                      self.geometry().width(),
                      self.geometry().height() - 21))

            vboxlayout = QVBoxLayout()
            vboxlayout.setContentsMargins(QtCore.QMargins())
            vboxlayout.setSpacing(0)
            sizegrip = QSizeGrip(self.centralwidget)
            sizegrip.setVisible(True)
            vboxlayout.addWidget(sizegrip, 0, Qt.AlignBottom | Qt.AlignRight)
            self.centralwidget.setLayout(vboxlayout)
            self.statusbar.hide()
コード例 #6
0
class Qshot(QWidget):
    def __init__(self, cfg_path, default_cfg_path, statics_path):
        super().__init__()
        self.cfg_path = cfg_path
        self.default_cfg_path = default_cfg_path
        self.statics_path = statics_path
        self.icon_path = os.path.join(statics_path, "icons", "Qs.ico")
        self.set_options()

        self.init_variables()
        self.init_ui()
        self.create_context_menu()
        self.create_tray_icon()

        self.init_Qshot_settings()
        self.init_global_keylistener()
        self.init_ss_handler()

        atexit.register(self.exit_app)

    # set up frame and options
    def set_options(self):
        """Reads cfg file and makes assignment to local variables
        shows error popup if cfg file has errors
        """
        try:
            # read cfg file
            with open(self.cfg_path, "r") as file:
                cfg = yaml.safe_load(file)

            # quickshot_frame
            # theme
            self.background_color = cfg["quickshot_frame"]["theme"][
                "background_color"]
            self.accent_color = cfg["quickshot_frame"]["theme"]["accent_color"]
            self.opacity = cfg["quickshot_frame"]["theme"]["opacity"]

            # hotkeys
            self.ss_hotkey = cfg["quickshot_frame"]["hotkeys"]["ss_hotkey"]
            self.hide_hotkey = cfg["quickshot_frame"]["hotkeys"]["hide_hotkey"]

            # utilities
            self.frame_delay = cfg["quickshot_frame"]["utilities"][
                "frame_delay"]

            # ss ss_handler
            # naming
            self.save_path = os.path.normpath(
                cfg["ss_handler"]["naming"]["save_path"])  # convert to path
            self.create_root_file = cfg["ss_handler"]["naming"][
                "create_root_file"]
            self.before_ss_name = cfg["ss_handler"]["naming"]["before_ss_name"]
            self.after_ss_name = cfg["ss_handler"]["naming"]["after_ss_name"]
            self.before_number = cfg["ss_handler"]["naming"]["before_number"]
            self.after_number = cfg["ss_handler"]["naming"]["after_number"]
            self.date_formatting = cfg["ss_handler"]["naming"][
                "date_formatting"]
            self.use_system_local_date_naming = cfg["ss_handler"]["naming"][
                "use_system_local_date_naming"]

            # ss options
            self.ss_extension = cfg["ss_handler"]["ss_options"]["ss_extension"]
            self.png_compression_level = cfg["ss_handler"]["ss_options"][
                "png_compression_level"]
            self.default_screen = cfg["ss_handler"]["ss_options"][
                "default_screen"]
            self.save_clipboard = cfg["ss_handler"]["ss_options"][
                "save_clipboard"]

        except Exception as e:
            print(e)
            self.show_alert_popup("There is a problem with cfg file")
            start_settings_with_event_loop(
                self.cfg_path, self.default_cfg_path,
                self.statics_path)  # start settings with its own event loop
            self.exit_app()

    def init_ui(self):
        """inits ui"""
        # set main frame options
        self.setWindowTitle("Quickshot")
        self.setWindowIcon(QtGui.QIcon(self.icon_path))
        self.setStyleSheet(self.window_style)
        self.setWindowOpacity(self.opacity)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint
                            | QtCore.Qt.WindowStaysOnTopHint)

        # init ui elements
        self.layouts()
        self.labels()
        self.buttons()
        self.sizegrips()
        self.setup_ui()
        self.show()

        self.resize(
            self.size()
        )  # new pyqt5 version (15.4) can't show back hidden frames properly if this line is not called at least once

    def init_variables(self):
        """init variables"""
        self.window_style = "background-color: {0}; border: 2px solid {1};".format(
            self.background_color, self.accent_color)
        self.label_style = "background-color: {0}; color: {1}; border: 0px".format(
            self.background_color, self.accent_color)
        self.button_style = "background-color: {0}; color: {1}; padding: 2px; border: 1px solid {1};".format(
            self.background_color, self.accent_color)

        self.background_color_temp = self.background_color
        self.accent_color_temp = self.accent_color

        # keeps old pointer position
        self.old_pos = None

        # keeps previous size for hidding and showing frame
        self.previous_size = self.size()

    def init_global_keylistener(self):
        """inits global keylistener on a QThread"""
        self.global_keylistener_thread = global_keylistener(
            self.ss_hotkey, self.hide_hotkey)
        self.global_keylistener_thread.start()

        # connect emitters to local class functions
        self.global_keylistener_thread.ss_trigger.connect(self.take_ss)
        self.global_keylistener_thread.hide_trigger.connect(self.hide_show)
        self.global_keylistener_thread.error_trigger.connect(
            self.global_keylistener_error)

    def init_ss_handler(self):
        """inits ss_handler 
        ss_handler handles taking ss and saving it to given path
        """
        self.ss_handler = ss_handler(
            ss_extension=self.ss_extension,
            save_path=self.save_path,
            create_root_file=self.create_root_file,
            before_ss_name=self.before_ss_name,
            after_ss_name=self.after_ss_name,
            before_number=self.before_number,
            after_number=self.after_number,
            date_formatting=self.date_formatting,
            use_system_local_date_naming=self.use_system_local_date_naming,
            png_compression_level=self.png_compression_level,
            default_screen=self.default_screen,
            save_clipboard=self.save_clipboard)

    def init_Qshot_settings(self):
        """intits Qshot settings and assigns local functions to emitters"""
        self.Qs_settings = Qshot_settings(self.cfg_path, self.default_cfg_path,
                                          self.statics_path)
        self.Qs_settings.oppcity_emitter.connect(self.change_opacity)
        self.Qs_settings.background_color_emitter.connect(
            self.change_background_color)
        self.Qs_settings.accent_color_emitter.connect(self.change_accent_color)
        self.Qs_settings.update_frame_emitter.connect(self.update_frame)
        self.Qs_settings.hide_frame_emitter.connect(self.hide_by_value)

    # add ui elements
    def setup_ui(self):
        """set up ui"""
        self.horizontal_layout_top.addWidget(self.sizegrip1)
        self.horizontal_layout_top.addStretch()
        self.horizontal_layout_top.addWidget(self.info_label)
        self.horizontal_layout_top.addStretch()
        self.horizontal_layout_top.addWidget(self.sizegrip2)

        self.horizontal_layout_bottom.addWidget(self.sizegrip3)
        self.horizontal_layout_bottom.addStretch()
        self.horizontal_layout_bottom.addWidget(self.ss_button)
        self.horizontal_layout_bottom.addStretch()
        self.horizontal_layout_bottom.addWidget(self.sizegrip4)

        self.vertical_layout.addLayout(self.horizontal_layout_top)
        self.vertical_layout.addStretch()
        self.vertical_layout.addLayout(self.horizontal_layout_bottom)

        self.setLayout(self.vertical_layout)

    def layouts(self):
        """adds layouts"""
        self.horizontal_layout_top = QHBoxLayout()
        self.horizontal_layout_bottom = QHBoxLayout()

        self.vertical_layout = QVBoxLayout()

    def labels(self):
        """adds labels"""
        self.info_label = QLabel()
        self.info_label.setText("Qshot")
        self.info_label.resize(150, 150)
        self.info_label.setFont(QFont('Arial', 12))
        self.info_label.setStyleSheet(self.label_style)

    def buttons(self):
        """adds buttons"""
        self.ss_button = QPushButton(self)
        self.ss_button.setText("shot")
        self.ss_button.setObjectName("ss_button")
        self.ss_button.setFont(QFont('Arial', 12))
        self.ss_button.setStyleSheet(self.button_style)
        self.ss_button.clicked.connect(self.on_button_click)

    def sizegrips(self):
        """adds sizegrips"""
        self.sizegrip1 = QSizeGrip(self)
        self.sizegrip1.setVisible(True)

        self.sizegrip2 = QSizeGrip(self)
        self.sizegrip2.setVisible(True)

        self.sizegrip3 = QSizeGrip(self)
        self.sizegrip3.setVisible(True)

        self.sizegrip4 = QSizeGrip(self)
        self.sizegrip4.setVisible(True)

    def create_context_menu(self):
        """context menu for right click and tray icon"""
        self.create_context_menu = QMenu()

        self.take_ss_action = self.create_context_menu.addAction("Take ss")
        self.take_ss_action.triggered.connect(self.take_ss)

        self.hide_show_action = self.create_context_menu.addAction("Hide/Show")
        self.hide_show_action.triggered.connect(self.hide_show)

        self.maximize_action = self.create_context_menu.addAction("Maximize")
        self.maximize_action.triggered.connect(self.maximize_window)

        self.maximize_action = self.create_context_menu.addAction("Minimize")
        self.maximize_action.triggered.connect(self.minimize_window)

        self.settings = self.create_context_menu.addAction("Settings")
        self.settings.triggered.connect(self.show_settings)

        self.exit_action = self.create_context_menu.addAction("Exit")
        self.exit_action.triggered.connect(self.exit_app)

    def create_tray_icon(self):
        """creates a tray icon if available and adds context menu to it"""
        self.create_tray_icon = QSystemTrayIcon(self)
        if (self.create_tray_icon.isSystemTrayAvailable()):
            self.create_tray_icon.setIcon(QIcon(self.icon_path))
            self.create_tray_icon.setContextMenu(self.create_context_menu)
            self.create_tray_icon.show()

    # event listeners
    def contextMenuEvent(self, event):
        """context menu functions has triggers so I don't need to use the event here, 
        but for right click menu to work function should stay"""
        action = self.create_context_menu.exec_(self.mapToGlobal(event.pos()))

    def mousePressEvent(self, event):
        """keeps old position on first press"""
        self.old_pos = event.globalPos()

    def mouseReleaseEvent(self, event):
        """resets old position on mouse relese to prevent moving on resize"""
        self.old_pos = None

    def mouseMoveEvent(self, event):
        """if old_pos exists moves the frame"""
        if (self.old_pos):
            delta = QPoint(event.globalPos() - self.old_pos)
            self.move(self.x() + delta.x(), self.y() + delta.y())
            self.old_pos = event.globalPos()

    def keyPressEvent(self, event):
        """regular keylistener"""
        if (event.key() == Qt.Key_Escape):
            self.exit_app()

    def on_button_click(self):
        """button click listener"""
        sender = self.sender()

        if (sender.objectName() == "ss_button"):
            self.take_ss()

    # error handling
    def show_alert_popup(self, alert_str):
        """shows alert popup with given message"""
        msg = QMessageBox()
        msg.setIcon(QMessageBox.Critical)
        msg.setWindowIcon(QtGui.QIcon(self.icon_path))
        msg.setWindowTitle("Alert")
        msg.setText(alert_str)
        msg.exec()

    def global_keylistener_error(self):
        """global keylistener error function"""
        self.show_alert_popup(
            "Hotkey error, please enter valid hotkeys or reset settings")
        self.show_settings()

    # settings functions
    def update_frame(self):
        """updates frame with new setting from config file, global keylistener has to be stop or it stays working at the background"""
        self.set_options()

        # update ui elements
        self.init_variables()
        self.setStyleSheet(self.window_style)
        self.setWindowOpacity(self.opacity)
        self.ss_button.setStyleSheet(self.button_style)
        self.info_label.setStyleSheet(self.label_style)

        # update global keylistener
        self.global_keylistener_thread.stop_keylistener()
        self.init_global_keylistener()

        # update ss handler
        self.init_ss_handler()

    def show_settings(self):
        """starts or refreshes settings frame 
        settings frame is not starts with main frame to increase startup speed.
        if settings not started, starts settings frame with ui elements.
        if settings is already started, refreshes the settings ui using form cfg file since old and not saved changes stuck in the ui
        """
        if (not self.Qs_settings.is_settings_started):
            self.Qs_settings.start_settings()
        else:
            self.Qs_settings.update_settings_ui()

    def change_background_color(self, value):
        if (value):
            self.background_color_temp = value
            self.window_style = "background-color: {0}; border: 2px solid {1};".format(
                self.background_color_temp, self.accent_color_temp)
            self.label_style = "background-color: {0}; color: {1}; border: 0px".format(
                self.background_color_temp, self.accent_color_temp)
            self.button_style = "background-color: {0}; color: {1}; padding: 2px; border: 1px solid {1};".format(
                self.background_color_temp, self.accent_color_temp)
        else:
            self.background_color_temp = self.background_color  # reset temp color on reverting settings
            self.window_style = "background-color: {0}; border: 2px solid {1};".format(
                self.background_color, self.accent_color)
            self.label_style = "background-color: {0}; color: {1}; border: 0px".format(
                self.background_color, self.accent_color)
            self.button_style = "background-color: {0}; color: {1}; padding: 2px; border: 1px solid {1};".format(
                self.background_color, self.accent_color)

        self.setStyleSheet(self.window_style)
        self.ss_button.setStyleSheet(self.button_style)
        self.info_label.setStyleSheet(self.label_style)

    def change_accent_color(self, value):
        if (value):
            self.accent_color_temp = value
            self.window_style = "background-color: {0}; border: 2px solid {1};".format(
                self.background_color_temp, self.accent_color_temp)
            self.label_style = "background-color: {0}; color: {1}; border: 0px".format(
                self.background_color_temp, self.accent_color_temp)
            self.button_style = "background-color: {0}; color: {1}; padding: 2px; border: 1px solid {1};".format(
                self.background_color_temp, self.accent_color_temp)
        else:
            self.accent_color_temp = self.accent_color  # reset temp color on reverting settings
            self.window_style = "background-color: {0}; border: 2px solid {1};".format(
                self.background_color, self.accent_color)
            self.label_style = "background-color: {0}; color: {1}; border: 0px".format(
                self.background_color, self.accent_color)
            self.button_style = "background-color: {0}; color: {1}; padding: 2px; border: 1px solid {1};".format(
                self.background_color, self.accent_color)

        self.setStyleSheet(self.window_style)
        self.ss_button.setStyleSheet(self.button_style)
        self.info_label.setStyleSheet(self.label_style)

    def change_opacity(self, value):
        """changes opacity or applies default if -1 is given"""
        if (value == -1):
            self.setWindowOpacity(self.opacity)
        else:
            self.setWindowOpacity(value)

    # utilities
    def hide_show(self):
        """hide show frame function for global keylistener"""
        if (self.isVisible()):
            self.hide()
            # self.create_tray_icon.showMessage("still running", "",  1)
        else:
            self.show()

    def hide_by_value(self, is_hide):
        """hide show frame function for displaying settings pop ups"""
        if (is_hide):
            self.hide()

        else:
            self.show()

    def center(self):
        """center the frame"""
        qr = self.frameGeometry()
        cp = QDesktopWidget().availableGeometry().center()
        qr.moveCenter(cp)
        self.move(qr.topLeft())

    def maximize_window(self):
        """maximizes frame"""
        screen = QDesktopWidget().screenGeometry()
        self.setGeometry(0, 0, screen.width(), screen.height())

    def minimize_window(self):
        """minimizes and centers the frame"""
        self.resize(200, 100)
        self.center()

    def exit_app(self):
        """hides tray icon before exit, also this function added to atexit to consider any other close app"""
        try:
            self.create_tray_icon.hide()
            sys.exit()
        except Exception as e:
            print(e)

    # main functionality
    def take_ss(self):
        """takes ss, uses ss_handler
        if frame is visible takes a partial ss if not takes all screen
        """
        if (self.isVisible()):
            bbox = self.geometry().getRect()
            bbox = {
                "top": bbox[1],
                "left": bbox[0],
                "width": bbox[2],
                "height": bbox[3]
            }

            # hide
            self.hide()
            # delay the frame visibility, on linux display compositor causes problems without delay
            time.sleep(self.frame_delay)
            ss_state, ss_info = self.ss_handler.take_ss(ss_bbox=bbox)
            # show
            self.show()

        else:
            ss_state, ss_info = self.ss_handler.take_ss()

        # on error
        if (not ss_state):
            self.show_alert_popup(ss_info)
コード例 #7
0
class PSticky(QDialog):
    closed = pyqtSignal()
    __title_bar_height__ = 32
    __bottom_grip__size__ = 16
    __window_margin__ = 1

    def __init__(self, parent: QWidget, inner: bool = False):
        if not inner:
            super().__init__()
        self.inner = inner
        self.__parent__ = parent
        if self.__parent__ is not None:

            self.__central_widget__ = None
            self.__follow__ = False

            self.HAnchor = Parapluie.HCenter
            self.VAnchor = Parapluie.VCenter

            self.__update_distance__ = False
            self.__const_hDistance__ = False
            self.__const_vDistance__ = False

            self.leftDistance = 0
            self.rightDistance = 0
            self.topDistance = 0
            self.bottomDistance = 0

            PFunction.applyStyle(self, PResource.stylesheet())

            self.setWindowFlags(Qt.FramelessWindowHint)

            self.setObjectName(Parapluie.Object_StickyWindow)

            self.title = QLabel("Parapluie")
            self.title.setStyleSheet("font-size: 14px; font-weight: bold;")
            self.title.setContentsMargins(8, 0, 8, 0)
            self.title.setMinimumHeight(self.__title_bar_height__)

            self.bottom_sizeGrip = QSizeGrip(self)
            self.bottom_sizeGrip.setObjectName(Parapluie.Object_StickyWindow_ResizeBottom)
            self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)

            self.titleBar = QHBoxLayout()
            self.titleBar.setContentsMargins(0, 0, 0, 0)
            self.titleBar.addWidget(self.title, alignment=Qt.AlignLeft | Qt.AlignCenter)
            self.titleBar.addStretch()

            self.moveWidget = PMoveWidget(self)
            self.moveWidget.setObjectName(Parapluie.Object_StickyWindow_FunctionButton)
            self.moveWidget.setLayout(self.titleBar)
            self.moveWidget.setMaximumHeight(self.__title_bar_height__)

            self.mainLayout = QVBoxLayout()
            self.mainLayout.setContentsMargins(self.__window_margin__, self.__window_margin__, self.__window_margin__,
                                               self.__window_margin__)
            self.mainLayout.setSpacing(0)
            self.mainLayout.addWidget(self.moveWidget, alignment=Qt.AlignTop)
            self.mainLayout.addWidget(self.bottom_sizeGrip, alignment=Qt.AlignRight)

            self.setLayout(self.mainLayout)

            if isinstance(parent, Sticky.PWindow):
                self.updateDistance()
                parent.resized.connect(self.followParentRelative)
                parent.closed.connect(self.close)
                parent.minimized.connect(self.minimizedFollowParent)

    def updateDistance(self):
        if self.__parent__ is not None:
            if not self.__const_hDistance__:
                self.leftDistance = self.x() - self.__parent__.x()
                self.rightDistance = (self.x() + self.width()) - self.__parent__.x() - self.__parent__.width()
            if not self.__const_vDistance__:
                self.topDistance = self.y() - self.__parent__.y()
                self.bottomDistance = (self.y() + self.height()) - self.__parent__.y() - self.__parent__.height()

    def moveEvent(self, a0: QtGui.QMoveEvent):
        if self.__parent__ is not None:
            super(PSticky, self).moveEvent(a0)
            if self.__update_distance__:
                self.updateDistance()

    def resizeEvent(self, a0: QtGui.QResizeEvent):
        if self.__parent__ is not None:
            super(PSticky, self).resizeEvent(a0)
            if self.__update_distance__:
                self.updateDistance()

    def closeEvent(self, a0: QtGui.QCloseEvent):
        if self.__parent__ is not None:
            self.completeDestroy(0)
            self.closed.emit()

    def setWindowTitle(self, *args):
        if self.__parent__ is not None:
            super(PSticky, self).setWindowTitle(*args)
            self.title.setText(*args)

    def setCentralWidget(self, widget: QWidget):
        if self.__parent__ is not None:
            self.mainLayout.insertWidget(1, widget)
            self.__central_widget__ = widget
            self.__central_widget__.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

    def addWindowAction(self, button):
        if self.__parent__ is not None:
            self.titleBar.addWidget(button, alignment=Qt.AlignLeft | Qt.AlignTop)

    def setResizable(self, resize=False):
        if self.__parent__ is not None:
            self.bottom_sizeGrip.setVisible(resize and not (self.__const_vDistance__ or self.__const_hDistance__))

    def isResizable(self):
        return self.bottom_sizeGrip.isVisible()

    def setMovable(self, movable: bool):
        if self.__parent__ is not None:
            self.moveWidget.setMovable(movable and not (self.__const_vDistance__ or self.__const_hDistance__))

    def isMovable(self) -> bool:
        return self.moveWidget.isMovable()

    def completeDestroy(self, code: int = 0):
        self.done(code)
        self.__parent__ = None

    def setAnchor(self, hAnchor: int, vAnchor: int, hDistance: int = None, vDistance: int = None):
        if self.__parent__ is not None:
            self.HAnchor = hAnchor
            self.VAnchor = vAnchor
            if hDistance is not None:
                self.leftDistance = hDistance
                self.rightDistance = hDistance
                self.__const_hDistance__ = True
            else:
                self.__const_hDistance__ = False
            if vDistance is not None:
                self.topDistance = vDistance
                self.bottomDistance = vDistance
                self.__const_vDistance__ = True
            else:
                self.__const_vDistance__ = False

            self.setMovable(not (self.__const_vDistance__ or self.__const_hDistance__))
            self.setResizable(not (self.__const_vDistance__ or self.__const_hDistance__))

            self.followParentRelative()

    def enableFollowParentRelative(self) -> bool:
        if self.__parent__ is not None:
            self.__follow__ = isinstance(self.__parent__, Sticky.PWindow)
            if self.__follow__:
                self.setWindowFlags(self.windowFlags() | Qt.WindowStaysOnTopHint)
            return self.__follow__
        return False

    def minimizedFollowParent(self):
        if self.__parent__ is not None:
            minimize = self.__parent__.isMinimized()
            if minimize:
                self.hide()
            else:
                self.show()
                self.followParentRelative()

    def followParentRelative(self):
        if self.__follow__ and self.__parent__ is not None:
            if self.inner:
                pPoint = self.__parent__.mapToGlobal(QPoint(self.__parent__.x(), self.__parent__.y()))
            else:
                pPoint = QPoint(0, 0)

            if self.HAnchor == Parapluie.HCenter:
                x = pPoint.x() + self.__parent__.width() / 2 - (self.width() / 2)
            elif self.HAnchor == Parapluie.Left:
                x = pPoint.x() + self.leftDistance
            elif self.HAnchor == Parapluie.Right:
                x = pPoint.x() + self.__parent__.width() + self.rightDistance - self.width()
            else:
                x = 0

            if self.VAnchor == Parapluie.VCenter:
                y = pPoint.y() + self.__parent__.height() / 2 - (self.height() / 2)
            elif self.VAnchor == Parapluie.Top:
                y = pPoint.y() + self.topDistance
            elif self.VAnchor == Parapluie.Bottom:
                y = pPoint.y() + self.__parent__.height() + self.bottomDistance - self.height()
            else:
                y = 0

            if x > self.__parent__.width():
                x = self.__parent__.width()
            elif x < 0:
                x = 0

            if y > self.__parent__.height():
                y = self.__parent__.height()
            elif y < 0:
                y = 0

            self.__update_distance__ = False
            self.move(x, y)
            self.__update_distance__ = True