如何解决pyside6 和 pyqt5 的区别
我正在 Pyside6 中编写程序并使用我自己的标题栏。 使用 pyside6 运行时,出现此问题。
使用 PyQt5 一切正常
这些框架在工作中的哪些差异会导致这个问题,以及应该使用什么来修复它。 两个框架上的代码是一样的,但是结果不一样,我不明白为什么会这样
我使用 PySide6 的代码
TextEditorQt.py
from PySide6 import QtGui
from PySide6.QtCore import *
from PySide6.QtGui import *
from PySide6.QtWidgets import *
from PySide6.QtWidgets import QApplication
from TextEditorUI import Ui_MainWindow,QMainWindow # импорт нашего сгенерированного файла
from PySide6.QtCore import QSettings,QPoint,QSize
from Titlebar import FramelessWindow
class Ui_MainWindow(object):
def setupUi(self,MainWindow):
if not MainWindow.objectName():
MainWindow.setObjectName(u"MainWindow")
MainWindow.resize(762,580)
MainWindow.setStyleSheet(u"")
self.open_action = QAction(MainWindow)
self.open_action.setObjectName(u"open_action")
self.newfile_action = QAction(MainWindow)
self.newfile_action.setObjectName(u"newfile_action")
self.save_action = QAction(MainWindow)
self.save_action.setObjectName(u"save_action")
self.saveas_action = QAction(MainWindow)
self.saveas_action.setObjectName(u"saveas_action")
self.exit_action = QAction(MainWindow)
self.exit_action.setObjectName(u"exit_action")
self.centralwidget = QWidget(MainWindow)
self.centralwidget.setObjectName(u"centralwidget")
self.gridLayout = QGridLayout(self.centralwidget)
self.gridLayout.setObjectName(u"gridLayout")
self.textEdit = QTextEdit(self.centralwidget)
self.textEdit.setObjectName(u"textEdit")
self.textEdit.setStyleSheet(u"alternate-background-color: rgb(85,255);\n"
"background-color: rgb(255,255,255);")
self.gridLayout.addWidget(self.textEdit,1,1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QMenuBar(MainWindow)
self.menubar.setObjectName(u"menubar")
self.menubar.setGeometry(QRect(0,762,22))
self.menu = QMenu(self.menubar)
self.menu.setObjectName(u"menu")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QStatusBar(MainWindow)
self.statusbar.setObjectName(u"statusbar")
MainWindow.setStatusBar(self.statusbar)
self.menubar.addAction(self.menu.menuAction())
self.menu.addAction(self.open_action)
self.menu.addAction(self.newfile_action)
self.menu.addAction(self.save_action)
self.menu.addAction(self.saveas_action)
self.menu.addSeparator()
self.menu.addAction(self.exit_action)
self.retranslateUi(MainWindow)
QMetaObject.connectSlotsByName(MainWindow)
# setupUi
def retranslateUi(self,MainWindow):
MainWindow.setWindowTitle(QCoreApplication.translate("MainWindow",u"Matewriter",None))
self.open_action.setText(
QCoreApplication.translate("MainWindow",u"\u041e\u0442\u043a\u0440\u044b\u0442\u044c",None))
self.newfile_action.setText(QCoreApplication.translate("MainWindow",u"\u041d\u043e\u0432\u044b\u0439",None))
self.save_action.setText(
QCoreApplication.translate("MainWindow",u"\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c",None))
self.saveas_action.setText(QCoreApplication.translate("MainWindow",u"\u0421\u043e\u0445\u0440\u0430\u043d\u0438\u0442\u044c \u043a\u0430\u043a...",None))
self.exit_action.setText(QCoreApplication.translate("MainWindow",u"\u0412\u044b\u0445\u043e\u0434",None))
# if QT_CONFIG(tooltip)
self.textEdit.setToolTip(
QCoreApplication.translate("MainWindow",u"<html><head/><body><p><br/></p></body></html>",None))
# endif // QT_CONFIG(tooltip)
self.menu.setTitle(QCoreApplication.translate("MainWindow",u"\u0424\u0430\u0439\u043b",None))
# retranslateUi
class MainWindow(QMainWindow,Ui_MainWindow):
def __init__(self,parent=None):
super(MainWindow,self).__init__(parent)
self.setWindowIcon(QtGui.QIcon('icon.ico'))
self.setupUi(self)
self.curFile = ''
self.setCurrentFile('')
self.createStatusBar()
self.textEdit.document().contentsChanged.connect(self.documentWasModified)
self.setCurrentFile('')
self.settings = QSettings('Matewriter','Matewriter')
self.exit_action.triggered.connect(QApplication.quit)
self.save_action.triggered.connect(self.save)
self.open_action.triggered.connect(self.open)
self.newfile_action.triggered.connect(self.newFile)
self.saveas_action.triggered.connect(self.saveAs)
self.open_action.setShortcut('Ctrl+O')
self.newfile_action.setShortcut('Ctrl+N')
self.save_action.setShortcut('Ctrl+S')
# Конфиги окна
windowScreenGeometry = self.settings.value("windowScreenGeometry")
windowScreenState = self.settings.value("windowScreenState")
if windowScreenGeometry:
self.restoreGeometry(windowScreenGeometry)
else:
# self.resize(600)
self.resize(600,600) # !!!
if windowScreenState:
self.restoreState(windowScreenState)
def closeEvent(self,event):
self.settings.setValue("windowScreenGeometry",self.saveGeometry())
self.settings.setValue("windowScreenState",self.saveState())
if self.maybeSave():
self.writeSettings()
event.accept()
else:
event.ignore()
def newFile(self):
if self.maybeSave():
self.textEdit.clear()
self.setCurrentFile('')
def open(self):
if self.maybeSave():
fileName,_ = QFileDialog.getOpenFileName(self)
if fileName:
self.loadFile(fileName)
def save(self):
if self.curFile:
return self.saveFile(self.curFile)
return self.saveAs()
def saveAs(self):
fileName,_ = QFileDialog.getSaveFileName(self)
if fileName:
return self.saveFile(fileName)
return False
def documentWasModified(self):
self.setWindowModified(self.textEdit.document().isModified())
def createStatusBar(self):
self.statusBar().showMessage("Ready")
def readSettings(self):
settings = QSettings("MateWriter")
pos = settings.value("pos",QPoint(200,200))
size = settings.value("size",QSize(400,400))
self.resize(size)
self.move(pos)
def writeSettings(self):
settings = QSettings("MateWriter")
settings.setValue("pos",self.pos())
settings.setValue("size",self.size())
def maybeSave(self):
if self.textEdit.document().isModified():
ret = QMessageBox.warning(self,"MateWriter","The document has been modified.\nDo you want to save "
"your changes?",QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
if ret == QMessageBox.Save:
return self.save()
if ret == QMessageBox.Cancel:
return False
return True
def loadFile(self,fileName):
file = QFile(fileName)
if not file.open(QFile.ReadOnly | QFile.Text):
QMessageBox.warning(self,"Cannot read file %s:\n%s." % (fileName,file.errorString()))
return
inf = QTextStream(file)
QApplication.setOverrideCursor(Qt.WaitCursor)
self.textEdit.setPlainText(inf.readAll())
QApplication.restoreOverrideCursor()
self.setCurrentFile(fileName)
self.statusBar().showMessage("File loaded",2000)
def saveFile(self,fileName):
file = QFile(fileName)
if not file.open(QFile.WriteOnly | QFile.Text):
QMessageBox.warning(self,"Cannot write file %s:\n%s." % (fileName,file.errorString()))
return False
outf = QTextStream(file)
QApplication.setOverrideCursor(Qt.WaitCursor)
outf << self.textEdit.toPlainText()
QApplication.restoreOverrideCursor()
self.setCurrentFile(fileName)
self.statusBar().showMessage("File saved",2000)
return True
def setCurrentFile(self,fileName):
self.curFile = fileName
self.textEdit.document().setModified(False)
self.setWindowModified(False)
if self.curFile:
shownName = self.strippedName(self.curFile)
else:
shownName = 'untitled.txt'
self.setWindowTitle(" %s[*] - MateWriter" % shownName)
def strippedName(self,fullFileName):
return QFileInfo(fullFileName).fileName()
if __name__ == '__main__':
import sys
app = QApplication(sys.argv)
app.setStyle('Fusion')
w = FramelessWindow()
w.setWindowTitle('Тестовая строка заголовка')
w.setWindowIcon(QIcon('Qt.ico'))
# w.setWidget(MainWindow(MainWindow)) # Добавить свое окно
w.setWidget(MainWindow()) # !!!
w.show()
sys.exit(app.exec_())
Titlebar.py
from PySide6.QtCore import Qt,Signal,QFileInfo
from PySide6.QtGui import QFont,QEnterEvent,QPainter,QColor,QPen
from PySide6.QtWidgets import (QWidget,QVBoxLayout,QHBoxLayout,QLabel,QSpacerItem,QSizePolicy,QPushButton)
class TitleBar(QWidget):
# Сигнал минимизации окна
windowMinimumed = Signal()
# увеличить максимальный сигнал окна
windowMaximumed = Signal()
# сигнал восстановления окна
windowNormaled = Signal()
# сигнал закрытия окна
windowClosed = Signal()
# Окно мобильных
windowMoved = Signal(QPoint)
# Сигнал Своя Кнопка +++
signalButtonMy = Signal()
def __init__(self,*args,**kwargs):
super(TitleBar,self).__init__(*args,**kwargs)
# Поддержка настройки фона qss
self.setAttribute(Qt.WA_StyledBackground,True)
self.mPos = None
self.iconSize = 20 # Размер значка по умолчанию
# Установите цвет фона по умолчанию,иначе он будет прозрачным из-за влияния родительского окна
self.setAutoFillBackground(True)
palette = self.palette()
palette.setColor(palette.Window,QColor(240,240,240))
self.setPalette(palette)
# макет
layout = QHBoxLayout(self,spacing=0)
layout.setContentsMargins(0,0)
# значок окна
self.iconLabel = QLabel(self)
self.iconLabel.setMargin(10)
# self.iconLabel.setScaledContents(True)
layout.addWidget(self.iconLabel)
# название окна
self.titleLabel = QLabel(self)
self.titleLabel.setMargin(2)
layout.addWidget(self.titleLabel)
# Средний телескопический бар
layout.addSpacerItem(QSpacerItem(
40,20,QSizePolicy.Expanding,QSizePolicy.Minimum))
# Использовать шрифты Webdings для отображения значков
font = self.font() or QFont()
font.setFamily('Webdings')
# Своя Кнопка ++++++++++++++++++++++++++
self.buttonMy = QPushButton(
'@',self,clicked=self.showButtonMy,font=font,objectName='buttonMy')
layout.addWidget(self.buttonMy)
# Свернуть кнопку
self.buttonMinimum = QPushButton(
'0',clicked=self.windowMinimumed.emit,objectName='buttonMinimum')
layout.addWidget(self.buttonMinimum)
# Кнопка Max / restore
self.buttonMaximum = QPushButton(
'1',clicked=self.showMaximized,objectName='buttonMaximum')
layout.addWidget(self.buttonMaximum)
# Кнопка закрытия
self.buttonClose = QPushButton(
'r',clicked=self.windowClosed.emit,objectName='buttonClose')
layout.addWidget(self.buttonClose)
# начальная высота
self.setHeight()
# +++ Вызывается по нажатию кнопки buttonMy
def showButtonMy(self):
print("Своя Кнопка ")
self.signalButtonMy.emit()
def showMaximized(self):
if self.buttonMaximum.text() == '1':
# Максимизировать
self.buttonMaximum.setText('2')
self.windowMaximumed.emit()
else: # Восстановить
self.buttonMaximum.setText('1')
self.windowNormaled.emit()
def setHeight(self,height=38):
""" Установка высоты строки заголовка """
self.setMinimumHeight(height)
self.setMaximumHeight(height)
# Задайте размер правой кнопки ?
self.buttonMinimum.setMinimumSize(height,height)
self.buttonMinimum.setMaximumSize(height,height)
self.buttonMaximum.setMinimumSize(height,height)
self.buttonMaximum.setMaximumSize(height,height)
self.buttonClose.setMinimumSize(height,height)
self.buttonClose.setMaximumSize(height,height)
self.buttonMy.setMinimumSize(height,height)
self.buttonMy.setMaximumSize(height,height)
def setTitle(self,title):
""" Установить заголовок """
self.titleLabel.setText(title)
def setIcon(self,icon):
""" настройки значокa """
self.iconLabel.setPixmap(icon.pixmap(self.iconSize,self.iconSize))
def setIconSize(self,size):
""" Установить размер значка """
self.iconSize = size
def enterEvent(self,event):
self.setCursor(Qt.ArrowCursor)
super(TitleBar,self).enterEvent(event)
def mouseDoubleClickEvent(self,event):
super(TitleBar,self).mouseDoubleClickEvent(event)
self.showMaximized()
def mousePressEvent(self,event):
""" Событие клика мыши """
if event.button() == Qt.LeftButton:
self.mPos = event.pos()
event.accept()
def mouseReleaseEvent(self,event):
''' Событие отказов мыши '''
self.mPos = None
event.accept()
def mouseMoveEvent(self,event):
if event.buttons() == Qt.LeftButton and self.mPos:
self.windowMoved.emit(self.mapToGlobal(event.pos() - self.mPos))
event.accept()
# Перечислить верхнюю левую,нижнюю правую и четыре неподвижные точки
Left,Top,Right,Bottom,LeftTop,RightTop,LeftBottom,RightBottom = range(8)
class FramelessWindow(QWidget):
# Четыре периметра
Margins = 5
def __init__(self,**kwargs):
super(FramelessWindow,**kwargs)
self._pressed = False
self.Direction = None
self.resize(762,580)
# Фон прозрачный
self.setAttribute(Qt.WA_TranslucentBackground,True)
# Нет границы
self.setWindowFlag(Qt.FramelessWindowHint)
# Отслеживание мыши
self.setMouseTracking(True)
# макет
layout = QVBoxLayout(self,spacing=0)
# Зарезервировать границы для изменения размера окна без полей
layout.setContentsMargins(
self.Margins,self.Margins,self.Margins)
# Панель заголовка
self.titleBar = TitleBar(self)
layout.addWidget(self.titleBar)
# слот сигнала
self.titleBar.windowMinimumed.connect(self.showMinimized)
self.titleBar.windowMaximumed.connect(self.showMaximized)
self.titleBar.windowNormaled.connect(self.showNormal)
self.titleBar.windowClosed.connect(self.close)
self.titleBar.windowMoved.connect(self.move)
self.windowTitleChanged.connect(self.titleBar.setTitle)
self.windowIconChanged.connect(self.titleBar.setIcon)
def setTitleBarHeight(self,height=38):
""" Установка высоты строки заголовка """
self.titleBar.setHeight(height)
def setIconSize(self,size):
""" Установка размера значка """
self.titleBar.setIconSize(size)
def setWidget(self,widget):
""" Настройте свои собственные элементы управления """
if hasattr(self,'_widget'):
return
self._widget = widget
# Установите цвет фона по умолчанию,иначе он будет прозрачным из-за влияния родительского окна
self._widget.setAutoFillBackground(True)
palette = self._widget.palette()
palette.setColor(palette.Window,240))
self._widget.setPalette(palette)
self._widget.installEventFilter(self)
self.layout().addWidget(self._widget)
def move(self,pos):
if self.windowState() == Qt.WindowMaximized or self.windowState() == Qt.WindowFullScreen:
# Максимизировать или полноэкранный режим не допускается
return
super(FramelessWindow,self).move(pos)
def showMaximized(self):
""" Чтобы максимизировать,удалите верхнюю,нижнюю,левую и правую границы.
Если вы не удалите его,в пограничной области будут пробелы. """
super(FramelessWindow,self).showMaximized()
self.layout().setContentsMargins(0,0)
def showNormal(self):
""" Восстановить,сохранить верхнюю и нижнюю левую и правую границы,иначе нет границы,которую нельзя отрегулировать """
super(FramelessWindow,self).showNormal()
self.layout().setContentsMargins(
self.Margins,self.Margins)
def eventFilter(self,obj,event):
""" Фильтр событий,используемый для решения мыши в других элементах
управления и восстановления стандартного стиля мыши """
if isinstance(event,QEnterEvent):
self.setCursor(Qt.ArrowCursor)
return super(FramelessWindow,self).eventFilter(obj,event)
def paintEvent(self,event):
""" Поскольку это полностью прозрачное фоновое окно,жесткая для поиска
граница с прозрачностью 1 рисуется в событии перерисовывания,чтобы отрегулировать размер окна. """
super(FramelessWindow,self).paintEvent(event)
painter = QPainter(self)
painter.setPen(QPen(QColor(255,1),2 * self.Margins))
painter.drawRect(self.rect())
def mousePressEvent(self,event):
""" Событие клика мыши """
super(FramelessWindow,self).mousePressEvent(event)
if event.button() == Qt.LeftButton:
self._mpos = event.pos()
self._pressed = True
def mouseReleaseEvent(self,event):
''' Событие отказов мыши '''
super(FramelessWindow,self).mouseReleaseEvent(event)
self._pressed = False
self.Direction = None
def mouseMoveEvent(self,event):
""" Событие перемещения мыши """
super(FramelessWindow,self).mouseMoveEvent(event)
pos = event.pos()
xPos,yPos = pos.x(),pos.y()
wm,hm = self.width() - self.Margins,self.height() - self.Margins
if self.isMaximized() or self.isFullScreen():
self.Direction = None
self.setCursor(Qt.ArrowCursor)
return
if event.buttons() == Qt.LeftButton and self._pressed:
self._resizeWidget(pos)
return
if xPos <= self.Margins and yPos <= self.Margins:
# Верхний левый угол
self.Direction = LeftTop
self.setCursor(Qt.SizeFDiagCursor)
elif wm <= xPos <= self.width() and hm <= yPos <= self.height():
# Нижний правый угол
self.Direction = RightBottom
self.setCursor(Qt.SizeFDiagCursor)
elif wm <= xPos and yPos <= self.Margins:
# верхний правый угол
self.Direction = RightTop
self.setCursor(Qt.SizeBDiagCursor)
elif xPos <= self.Margins and hm <= yPos:
# Нижний левый угол
self.Direction = LeftBottom
self.setCursor(Qt.SizeBDiagCursor)
elif 0 <= xPos <= self.Margins and self.Margins <= yPos <= hm:
# Влево
self.Direction = Left
self.setCursor(Qt.SizeHorCursor)
elif wm <= xPos <= self.width() and self.Margins <= yPos <= hm:
# Право
self.Direction = Right
self.setCursor(Qt.SizeHorCursor)
elif self.Margins <= xPos <= wm and 0 <= yPos <= self.Margins:
# выше
self.Direction = Top
self.setCursor(Qt.SizeVerCursor)
elif self.Margins <= xPos <= wm and hm <= yPos <= self.height():
# ниже
self.Direction = Bottom
self.setCursor(Qt.SizeVerCursor)
def _resizeWidget(self,pos):
""" Отрегулируйте размер окна """
if self.Direction == None:
return
mpos = pos - self._mpos
xPos,yPos = mpos.x(),mpos.y()
geometry = self.geometry()
x,y,w,h = geometry.x(),geometry.y(),geometry.width(),geometry.height()
if self.Direction == LeftTop: # Верхний левый угол
if w - xPos > self.minimumWidth():
x += xPos
w -= xPos
if h - yPos > self.minimumHeight():
y += yPos
h -= yPos
elif self.Direction == RightBottom: # Нижний правый угол
if w + xPos > self.minimumWidth():
w += xPos
self._mpos = pos
if h + yPos > self.minimumHeight():
h += yPos
self._mpos = pos
elif self.Direction == RightTop: # верхний правый угол
if h - yPos > self.minimumHeight():
y += yPos
h -= yPos
if w + xPos > self.minimumWidth():
w += xPos
self._mpos.setX(pos.x())
elif self.Direction == LeftBottom: # Нижний левый угол
if w - xPos > self.minimumWidth():
x += xPos
w -= xPos
if h + yPos > self.minimumHeight():
h += yPos
self._mpos.setY(pos.y())
elif self.Direction == Left: # Влево
if w - xPos > self.minimumWidth():
x += xPos
w -= xPos
else:
return
elif self.Direction == Right: # Право
if w + xPos > self.minimumWidth():
w += xPos
self._mpos = pos
else:
return
elif self.Direction == Top: # выше
if h - yPos > self.minimumHeight():
y += yPos
h -= yPos
else:
return
elif self.Direction == Bottom: # ниже
if h + yPos > self.minimumHeight():
h += yPos
self._mpos = pos
else:
return
self.setGeometry(x,h)
解决方法
原因是不支持 QVBoxLayout 的命名参数
layout = QVBoxLayout(self,spacing=0)
属性需要通过调用setter来设置。
layout = QVBoxLayout(self)
layout.setSpacing(0)
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。