Левое меню с использованием Qt Designer и Python 3 (PyQt5)
Пыталась сделать левое меню с помощью QTabWidget для переключения между разделами программы, вроде такого:
Я использую Qt Designer и Python. В дизайнере можно установить tabPosition равным West, но при таком решении текст также становится вертикальным:
Из этого вопроса я взяла код и попыталась адаптировать его под свою задачу, но вот что вышло:
Как правильно совместить файл .ui и настройку QTabWidget для получения нужного результата?
Также смотрела пример из вопроса, но адаптировать его под файл .ui мне не удалось. Вот код:
import sys
from PyQt5 import QtCore, uic, QtWidgets
from PyQt5.QtWidgets import QApplication, QMainWindow
class ProxyStyle(QtWidgets.QProxyStyle):
def drawControl(self, element, opt, painter, widget):
if element == QtWidgets.QStyle.CE_TabBarTabLabel:
ic = self.pixelMetric(QtWidgets.QStyle.PM_TabBarIconSize)
r = QtCore.QRect(opt.rect)
w = 0 if opt.icon.isNull() else opt.rect.width() + self.pixelMetric(QtWidgets.QStyle.PM_TabBarIconSize)
r.setHeight(opt.fontMetrics.width(opt.text) + w)
r.moveBottom(opt.rect.bottom())
opt.rect = r
QtWidgets.QProxyStyle.drawControl(self, element, opt, painter, widget)
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
uic.loadUi('untitled.ui', self)
QtWidgets.QApplication.setStyle(ProxyStyle())
self.show()
if __name__ == '__main__':
app = QApplication(sys.argv)
w = Window()
w.show()
sys.exit(app.exec_())
untitled.ui - файл интерфейса с одним QTabWidget.
И возможно ли кастомизировать такие пункты меню? Сделать их закруглёнными, добавить иконки и т.д. в Qt Designer?
Ответы (1 шт):
Вы не можете в Qt Designer сделать такую настройку.
Но вы можете вставить в Qt Designer любой переопределенный вами виджет.
Посмотрите пост Как встроить график на форму в Qt Designer? там подробно все описано.
Создали .ui, далее:
q1297730.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>355</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="TabWidget" name="tabWidget">
<property name="tabPosition">
<enum>QTabWidget::West</enum>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Tab 1</string>
</attribute>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Tab 2</string>
</attribute>
</widget>
</widget>
</item>
</layout>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>376</width>
<height>21</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<customwidgets>
<customwidget>
<class>TabWidget</class>
<extends>QTabWidget</extends>
<header>tabwidget</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
Конвертируем .ui в .py
pyuic5 q1297730.ui -o q1297730_ui.py -x
q1297730_ui.py
Вносим в него некоторые дополнения.
from PyQt5 import QtCore, QtGui, QtWidgets
from tabwidget import TabWidget # +++
class Ui_MainWindow(object):
def setupUi(self, MainWindow):
MainWindow.setObjectName("MainWindow")
MainWindow.resize(376, 355)
self.centralwidget = QtWidgets.QWidget(MainWindow)
self.centralwidget.setObjectName("centralwidget")
self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
self.gridLayout.setObjectName("gridLayout")
self.tabWidget = TabWidget(self.centralwidget)
self.tabWidget.setTabPosition(QtWidgets.QTabWidget.West)
self.tabWidget.setObjectName("tabWidget")
self.tab = QtWidgets.QWidget()
self.tab.setObjectName("tab")
# self.tabWidget.addTab(self.tab, "") # ---
self.tabWidget.addTab(self.tab, QtGui.QIcon("Ok.png"), "") # +++
self.tab_2 = QtWidgets.QWidget()
self.tab_2.setObjectName("tab_2")
# self.tabWidget.addTab(self.tab_2, "") # ---
self.tabWidget.addTab(self.tab_2, QtGui.QIcon("lena.jpg"), "") # +++
self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
MainWindow.setCentralWidget(self.centralwidget)
self.menubar = QtWidgets.QMenuBar(MainWindow)
self.menubar.setGeometry(QtCore.QRect(0, 0, 376, 21))
self.menubar.setObjectName("menubar")
MainWindow.setMenuBar(self.menubar)
self.statusbar = QtWidgets.QStatusBar(MainWindow)
self.statusbar.setObjectName("statusbar")
MainWindow.setStatusBar(self.statusbar)
self.retranslateUi(MainWindow)
QtCore.QMetaObject.connectSlotsByName(MainWindow)
def retranslateUi(self, MainWindow):
_translate = QtCore.QCoreApplication.translate
MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "Tab 1"))
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Tab 2"))
#from tabwidget import TabWidget # ---
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
MainWindow = QtWidgets.QMainWindow()
ui = Ui_MainWindow()
ui.setupUi(MainWindow)
MainWindow.show()
sys.exit(app.exec_())
Создаем модуль tabwidget.py, который содержит то что нам нужно:
tabwidget.py
from PyQt5 import QtCore, QtGui, QtWidgets
class ProxyStyle(QtWidgets.QProxyStyle):
def drawControl(self, element, opt, painter, widget):
if element == QtWidgets.QStyle.CE_TabBarTabLabel:
ic = self.pixelMetric(QtWidgets.QStyle.PM_TabBarIconSize)
r = QtCore.QRect(opt.rect)
w = 0 if opt.icon.isNull() else opt.rect.width() + self.pixelMetric(QtWidgets.QStyle.PM_TabBarIconSize)
r.setHeight(opt.fontMetrics.width(opt.text) + w)
r.moveBottom(opt.rect.bottom())
opt.rect = r
QtWidgets.QProxyStyle.drawControl(self, element, opt, painter, widget)
class TabBar(QtWidgets.QTabBar):
def tabSizeHint(self, index):
s = QtWidgets.QTabBar.tabSizeHint(self, index)
s.transpose()
return s
def paintEvent(self, event):
painter = QtWidgets.QStylePainter(self)
opt = QtWidgets.QStyleOptionTab()
for i in range(self.count()):
self.initStyleOption(opt, i)
painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt)
painter.save()
s = opt.rect.size()
s.transpose()
r = QtCore.QRect(QtCore.QPoint(), s)
r.moveCenter(opt.rect.center())
opt.rect = r
c = self.tabRect(i).center()
painter.translate(c)
painter.rotate(90)
painter.translate(-c)
painter.drawControl(QtWidgets.QStyle.CE_TabBarTabLabel, opt);
painter.restore()
class TabWidget(QtWidgets.QTabWidget):
def __init__(self, *args, **kwargs):
QtWidgets.QTabWidget.__init__(self, *args, **kwargs)
self.setTabBar(TabBar(self))
self.setTabPosition(QtWidgets.QTabWidget.West)
Запускаем python q1297730_ui.py
Update
Подскажите как правильно загрузить файл .ui? Я переопределила виджет и создала файл tabwidget.py, загрузила файл интерфейса с помощью
uic.loadUiи вкладки стали горизонтальными, но текст выводится так же, как и у меня на скриншоте в вопросе.
import sys
from PyQt5 import QtCore, QtGui, QtWidgets, uic
from PyQt5.Qt import *
from tabwidget import TabWidget, ProxyStyle # +++ ProxyStyle
class Window(QMainWindow):
def __init__(self):
super(Window, self).__init__()
uic.loadUi('q1297730.ui', self)
self.tabWidget.addTab(self.tab, QtGui.QIcon("Ok.png"), " Tab 1") # +++
self.tabWidget.addTab(self.tab_2, QtGui.QIcon("lena.jpg"), " Tab 2") # +++
if __name__ == '__main__':
app = QApplication(sys.argv)
app.setStyle(ProxyStyle()) # +++
w = Window()
w.show()
sys.exit(app.exec_())







