PyQt5可拖动无框窗口

时间:2016-06-09 06:26:17

标签: python windows python-3.4 pyqt5 qmainwindow

我找到了一个在无框窗口上设置边框的示例,但是它不可拖动。如何使无框窗口可拖动?特别是如果我能看到一个例子,它会很棒。这是我的示例代码(通常代码更长,这就是为什么有很多库只是不要介意它们);

CameraCaptureUI capture = new CameraCaptureUI();

capture.PhotoSettings.Format = CameraCaptureUIPhotoFormat.Jpeg;

capture.PhotoSettings.CroppedAspectRatio = new Size(1, 2);

capture.PhotoSettings.MaxResolution=CameraCaptureUIMaxPhotoResolution.HighestAvailable

StorageFile storeFile=await capture.CaptureFileAsync(CameraCaptureUIMode.Photo);

if (storeFile != null)
{
    var stream = await storeFile.OpenAsync(FileAccessMode.Read);

    BitmapImage bimage = new BitmapImage();

    bimage.SetSource(stream);

    Image imageitem = new Image();

    imageitem.Source = bimage;

    my_canvas.Children.Add(imageitem);

2 个答案:

答案 0 :(得分:4)

您需要自己处理鼠标事件。

  • 我们需要在mousePressEvent上添加一个事件,该事件将保留我们最后一次点击窗口的位置
  • 然后,我们将添加mouseMoveEvent,它将计算最后点击的点与当前鼠标位置之间的距离。我们将按照这个距离移动窗口。

这是固定代码:

from PyQt5.QtWidgets import (QMessageBox,QApplication, QWidget, QToolTip, QPushButton,
                             QDesktopWidget, QMainWindow, QAction, qApp, QToolBar, QVBoxLayout,
                             QComboBox,QLabel,QLineEdit,QGridLayout,QMenuBar,QMenu,QStatusBar,
                             QTextEdit,QDialog,QFrame,QProgressBar
                             )
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtGui import QIcon,QFont,QPixmap,QPalette
from PyQt5.QtCore import QCoreApplication, Qt,QBasicTimer, QPoint

import sys

class cssden(QMainWindow):
    def __init__(self):
        super().__init__()


        self.mwidget = QMainWindow(self)
        self.setWindowFlags(QtCore.Qt.FramelessWindowHint)


        #size
        self.setFixedSize(320, 450)
        self.center()


        #label
        self.lbl = QLabel(self)
        self.lbl.setText("test")
        self.lbl.setStyleSheet("background-color: rgb(0,0,0);"
                               "border: 1px solid red;"
                               "color: rgb(255,255,255);"
                               "font: bold italic 20pt 'Times New Roman';")
        self.lbl.setGeometry(5,5,60,40)

        self.oldPos = self.pos()

        self.show()

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

    def mousePressEvent(self, event):
        self.oldPos = event.globalPos()

    def mouseMoveEvent(self, event):
        delta = QPoint (event.globalPos() - self.oldPos)
        #print(delta)
        self.move(self.x() + delta.x(), self.y() + delta.y())
        self.oldPos = event.globalPos()

app = QApplication(sys.argv)
app.setStyleSheet("QMainWindow{background-color: darkgray;border: 1px solid black}")

ex = cssden()
sys.exit(app.exec_())

答案 1 :(得分:2)

这里是可拖动和可调整大小的无框窗口

from PyQt5.QtGui import *
from PyQt5.QtCore import *
from PyQt5.QtWidgets import *


class movable_label(QLabel):
    def __init__(self, parent):
        super().__init__(parent)

        self.parent = parent

        self.setStyleSheet("background-color: #ccc")
        self.setMinimumHeight(30)

    def mousePressEvent(self, e):
        if e.button() == Qt.LeftButton:
            if self.parent.press_control == 0:
                self.pos = e.pos()
                self.main_pos = self.parent.pos()
        super().mousePressEvent(e)
    def mouseMoveEvent(self, e):
        if self.parent.cursor().shape() == Qt.ArrowCursor:
            self.last_pos = e.pos() - self.pos
            self.main_pos += self.last_pos
            self.parent.move(self.main_pos)
        super(movable_label, self).mouseMoveEvent(e)


class main(QMainWindow):
    def __init__(self):
        super().__init__()
        
        self.setWindowFlags(Qt.FramelessWindowHint)
        self.central = QWidget()

        self.vbox = QVBoxLayout(self.central)
        self.vbox.addWidget(movable_label(self))
        self.vbox.addWidget(QPushButton("Click"))
        self.vbox.setAlignment(Qt.AlignTop)
        self.vbox.setSpacing(0)
        self.vbox.setContentsMargins(0,0,0,0)
        
        self.press_control = 0        
        
        self.setCentralWidget(self.central)
        self.resize(800,500)
        self.show()          

    def eventFilter(self, obj, e):
        #hovermoveevent
        if e.type() == 129:
            if self.press_control == 0:
                self.pos_control(e)#cursor position control for cursor shape setup

        #mousepressevent
        if e.type() == 2:
            self.press_control = 1
            self.origin = self.mapToGlobal(e.pos())
            self.ori_geo = self.geometry()

        #mousereleaseevent
        if e.type() == 3:

            self.press_control = 0
            self.pos_control(e)
        
        #mosuemoveevent
        if e.type() == 5:
            if self.cursor().shape() != Qt.ArrowCursor:
                self.resizing(self.origin, e, self.ori_geo, self.value)

        return True

    def pos_control(self, e):
        rect = self.rect()
        top_left = rect.topLeft()
        top_right = rect.topRight()
        bottom_left = rect.bottomLeft()
        bottom_right = rect.bottomRight()
        pos = e.pos()

        #top catch
        if pos in QRect(QPoint(top_left.x()+5,top_left.y()), QPoint(top_right.x()-5,top_right.y()+5)):
            self.setCursor(Qt.SizeVerCursor)
            self.value = 1

        #bottom catch
        elif pos in QRect(QPoint(bottom_left.x()+5,bottom_left.y()), QPoint(bottom_right.x()-5,bottom_right.y()-5)):
            self.setCursor(Qt.SizeVerCursor)
            self.value = 2
        
        #right catch
        elif pos in QRect(QPoint(top_right.x()-5,top_right.y()+5), QPoint(bottom_right.x(),bottom_right.y()-5)):
            self.setCursor(Qt.SizeHorCursor)
            self.value = 3

        #left catch
        elif pos in QRect(QPoint(top_left.x()+5,top_left.y()+5), QPoint(bottom_left.x(),bottom_left.y()-5)):
            self.setCursor(Qt.SizeHorCursor)
            self.value = 4

        #top_right catch
        elif pos in QRect(QPoint(top_right.x(),top_right.y()), QPoint(top_right.x()-5,top_right.y()+5)):
            self.setCursor(Qt.SizeBDiagCursor)
            self.value = 5

        #botom_left catch
        elif pos in QRect(QPoint(bottom_left.x(),bottom_left.y()), QPoint(bottom_left.x()+5,bottom_left.y()-5)):
            self.setCursor(Qt.SizeBDiagCursor)
            self.value = 6

        #top_left catch
        elif pos in QRect(QPoint(top_left.x(),top_left.y()), QPoint(top_left.x()+5,top_left.y()+5)):
            self.setCursor(Qt.SizeFDiagCursor)
            self.value = 7

        #bottom_right catch
        elif pos in QRect(QPoint(bottom_right.x(),bottom_right.y()), QPoint(bottom_right.x()-5,bottom_right.y()-5)):
            self.setCursor(Qt.SizeFDiagCursor)
            self.value = 8
        
        #default
        else:
            self.setCursor(Qt.ArrowCursor)       

    def resizing(self, ori, e, geo, value):    
        #top_resize
        if self.value == 1:
            last = self.mapToGlobal(e.pos())-ori
            first = geo.height()
            first -= last.y()
            Y = geo.y()
            Y += last.y()

            if first > self.minimumHeight():
                self.setGeometry(geo.x(), Y, geo.width(), first)                    
        
        #bottom_resize
        if self.value == 2:
            last = self.mapToGlobal(e.pos())-ori
            first = geo.height()
            first += last.y()
            self.resize(geo.width(), first)

        #right_resize
        if self.value == 3:
            last = self.mapToGlobal(e.pos())-ori
            first = geo.width()
            first += last.x()
            self.resize(first, geo.height())

        #left_resize
        if self.value == 4:
            last = self.mapToGlobal(e.pos())-ori
            first = geo.width()
            first -= last.x()
            X = geo.x()
            X += last.x()

            if first > self.minimumWidth():
                self.setGeometry(X, geo.y(), first, geo.height())

        #top_right_resize
        if self.value == 5:
            last = self.mapToGlobal(e.pos())-ori
            first_width = geo.width()
            first_height = geo.height()
            first_Y = geo.y()
            first_width += last.x()
            first_height -= last.y()
            first_Y += last.y()
                
            if first_height > self.minimumHeight():
                self.setGeometry(geo.x(), first_Y, first_width, first_height)

        #bottom_right_resize
        if self.value == 6:
            last = self.mapToGlobal(e.pos())-ori
            first_width = geo.width()
            first_height = geo.height()
            first_X = geo.x()
            first_width -= last.x()
            first_height += last.y()
            first_X += last.x()
                
            if first_width > self.minimumWidth():
                self.setGeometry(first_X, geo.y(), first_width, first_height)

        #top_left_resize
        if self.value == 7:
            last = self.mapToGlobal(e.pos())-ori
            first_width = geo.width()
            first_height = geo.height()
            first_X = geo.x()
            first_Y = geo.y()
            first_width -= last.x()
            first_height -= last.y()
            first_X += last.x()
            first_Y += last.y()
                
            if first_height > self.minimumHeight() and first_width > self.minimumWidth():
                self.setGeometry(first_X, first_Y, first_width, first_height)

        #bottom_right_resize
        if self.value == 8:
            last = self.mapToGlobal(e.pos())-ori
            first_width = geo.width()
            first_height = geo.height()
            first_width += last.x()
            first_height += last.y()                    
            
            self.setGeometry(geo.x(), geo.y(), first_width, first_height)           



app = QApplication([])
window = main()
window.installEventFilter(window)
app.exec()