pyqt5 tabwidget垂直选项卡水平文本对齐左侧

2024-07-04 08:14:16 发布

您现在位置:Python中文网/ 问答频道 /正文

因为pyqt在垂直选项卡选项中没有水平文本,所以我遵循这个link来实现它。 我想在左边有图标,然后是图标后面的文本,以及所选选项卡文本、非活动选项卡文本的不同颜色。下面的代码几乎可以完成它。唯一的问题是文本对齐是居中对齐。我试图更改tabRect.center(),但用left和top或right等更改它会导致崩溃

我从this link得到的注释代码使我左对齐,但它没有我添加的图标。但我无法更改非活动选项卡的文本颜色

我是python新手,无法找到解决方案。我也尝试过这个link,但它只设置背景色。也尝试使用此选项setTabTextColor link,但由于某些原因,它不起作用。从2天开始一直在尝试

每当我尝试使用带有注释代码的样式表设置文本颜色时,“颜色”选项在样式表中就不起作用。有什么办法可以做到这一点吗?谢谢

from PyQt5 import QtCore, QtGui, QtWidgets

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()

        # for i in range(self.count()):
        #     self.initStyleOption(opt, i)
        #     c = self.tabRect(i)
        #     c.moveLeft(35)
        #     painter.drawControl(QtWidgets.QStyle.CE_TabBarTabShape, opt)
        #     # painter.setPen(QColor(255, 255, 255))
        #     painter.drawText(c, QtCore.Qt.AlignVCenter | QtCore.Qt.TextDontClip, self.tabText(i))
        #     if i == 0:
        #         painter.drawImage(QtCore.QRectF(8, 8, 20, 20), QtGui.QImage("images/logo.png"))
        #     if i == 1:
        #         painter.drawImage(QtCore.QRectF(8, 44, 20, 20), QtGui.QImage("images/data.png"))
        #     if i == 2:
        #         painter.drawImage(QtCore.QRectF(8, 82, 20, 20), QtGui.QImage("images/browse.png"))
        #     if i == 3:
        #         painter.drawImage(QtCore.QRectF(8, 120, 20, 20), QtGui.QImage("images/off.png"))
        #     if i == 4:
        #         painter.drawImage(QtCore.QRectF(8, 158, 20, 20), QtGui.QImage("images/cal.png"))
        #     if i == 5:
        #         painter.drawImage(QtCore.QRectF(8, 196, 20, 20), QtGui.QImage("images/fol.png"))
        #     if i == 6:
        #         painter.drawImage(QtCore.QRectF(8, 232, 20, 20), QtGui.QImage("images/exc.png"))
        # painter.end()


class TabWidget(QtWidgets.QTabWidget):
    def __init__(self, *args, **kwargs):
        QtWidgets.QTabWidget.__init__(self, *args, **kwargs)
        self.setTabBar(TabBar(self))
        self.setTabPosition(QtWidgets.QTabWidget.West)

Tags: 文本selfifpnglink选项卡imagesopt
3条回答

我无法只使用文本(而不是图标)处理first answer,因为我的文本被剪切。 即使我能够运行second answer,我认为这还不清楚。 所以我的答案是:
此代码使用second answer's code定义VerticalTabWidget类:

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

class TabBar(QTabBar):
    def tabSizeHint(self, index):
        s = QTabBar.tabSizeHint(self, index)
        s.transpose()
        return s

    def paintEvent(self, event):
        painter = QStylePainter(self)
        opt = QStyleOptionTab()

        for i in range(self.count()):
            self.initStyleOption(opt, i)
            painter.drawControl(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(QStyle.CE_TabBarTabLabel, opt)
            painter.restore()

class VerticalTabWidget(QTabWidget):
    def __init__(self, *args, **kwargs):
        QTabWidget.__init__(self, *args, **kwargs)
        self.setTabBar(TabBar())
        self.setTabPosition(QtWidgets.QTabWidget.West)

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

        tabs = VerticalTabWidget()
        tabs.addTab(QWidget(), "First Tab")
        tabs.addTab(QWidget(), "Second Tab")
        tabs.addTab(QWidget(), "Third Tab")

        self.setCentralWidget(tabs)

if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = app_window()
    w.show()
    sys.exit(app.exec_())

您只需将TabBarVerticalTabWidget类复制到代码中,并将VerticalTabWidget用作任何QTabWidget

解决方案是使用QProxyStyle重定向文本绘制:

from PyQt5 import QtCore, QtGui, QtWidgets


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)

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)

if __name__ == '__main__':
    import sys

    app = QtWidgets.QApplication(sys.argv)
    QtWidgets.QApplication.setStyle(ProxyStyle())
    w = TabWidget()
    w.addTab(QtWidgets.QWidget(), QtGui.QIcon("zoom.png"), "ABC")
    w.addTab(QtWidgets.QWidget(), QtGui.QIcon("zoom-in.png"), "ABCDEFGH")
    w.addTab(QtWidgets.QWidget(), QtGui.QIcon("zoom-out.png"), "XYZ")

    w.resize(640, 480)
    w.show()

    sys.exit(app.exec_())

enter image description here

如果您以前在QtDesigner中设计过任何选项卡。 例如,我在QtDesigner中设计了此选项卡: enter image description here

现在我已经从ui文件生成了py文件,ui文件如下所示:

# -*- coding: utf-8 -*-

# Form implementation generated from reading ui file 'tabwidget.ui'
#
# Created by: PyQt5 UI code generator 5.13.2
#
# WARNING! All changes made in this file will be lost!


from PyQt5 import QtCore, QtGui, QtWidgets


class Ui_MainWindow(object):
    def setupUi(self, MainWindow):
        MainWindow.setObjectName("MainWindow")
        MainWindow.resize(800, 600)
        self.centralwidget = QtWidgets.QWidget(MainWindow)
        self.centralwidget.setObjectName("centralwidget")
        self.gridLayout = QtWidgets.QGridLayout(self.centralwidget)
        self.gridLayout.setObjectName("gridLayout")
        self.tabWidget = QtWidgets.QTabWidget(self.centralwidget)
        self.tabWidget.setObjectName("tabWidget")
        self.tab = QtWidgets.QWidget()
        self.tab.setObjectName("tab")
        self.gridLayout_2 = QtWidgets.QGridLayout(self.tab)
        self.gridLayout_2.setObjectName("gridLayout_2")
        self.pushButton_reach = QtWidgets.QPushButton(self.tab)
        self.pushButton_reach.setObjectName("pushButton_reach")
        self.gridLayout_2.addWidget(self.pushButton_reach, 1, 1, 1, 1)
        self.label = QtWidgets.QLabel(self.tab)
        self.label.setAlignment(QtCore.Qt.AlignCenter)
        self.label.setObjectName("label")
        self.gridLayout_2.addWidget(self.label, 0, 1, 1, 1)
        self.tabWidget.addTab(self.tab, "")
        self.tab_2 = QtWidgets.QWidget()
        self.tab_2.setObjectName("tab_2")
        self.tabWidget.addTab(self.tab_2, "")
        self.gridLayout.addWidget(self.tabWidget, 0, 0, 1, 1)
        self.pushButton_addoptions = QtWidgets.QPushButton(self.centralwidget)
        self.pushButton_addoptions.setObjectName("pushButton_addoptions")
        self.gridLayout.addWidget(self.pushButton_addoptions, 1, 0, 1, 1)
        MainWindow.setCentralWidget(self.centralwidget)
        self.statusbar = QtWidgets.QStatusBar(MainWindow)
        self.statusbar.setObjectName("statusbar")
        MainWindow.setStatusBar(self.statusbar)

        self.retranslateUi(MainWindow)
        self.tabWidget.setCurrentIndex(0)
        QtCore.QMetaObject.connectSlotsByName(MainWindow)

    def retranslateUi(self, MainWindow):
        _translate = QtCore.QCoreApplication.translate
        MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow"))
        self.pushButton_reach.setText(_translate("MainWindow", "I am here"))
        self.label.setText(_translate("MainWindow", "Gotcha!"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), _translate("MainWindow", "First Tab"))
        self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), _translate("MainWindow", "Second Tab"))
        self.pushButton_addoptions.setText(_translate("MainWindow", "ADD options"))

根据eyllanesc的回答,我找到了如何垂直添加选项卡的方法,并将预先存在的第一个选项卡添加到修改后的tabwidget中,如下所示:

import sys
from PyQt5.QtWidgets import QMainWindow, QApplication
from PyQt5 import QtGui, QtWidgets, QtCore
import tabwidget


# new additions
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)

# new additions


class app_window(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = tabwidget.Ui_MainWindow()
        self.ui.setupUi(self)
        # self.ui.tabWidget = TabWidget()
        self.ui.tabWidget.setTabBar(TabBar(self.ui.tabWidget))
        self.ui.tabWidget.setTabPosition(self.ui.tabWidget.West)
        self.ui.tabWidget.insertTab(0, self.ui.tab, "My tab")
        self.ui.pushButton_reach.clicked.connect(self.display)
        self.show()

    def display(self):
        print("reached")
        self.close()


if __name__ == '__main__':
    app = QApplication(sys.argv)
    w = app_window()
    w.show()
    sys.exit(app.exec_())

现在我的窗口如下所示: enter image description here

我希望这将解决许多人的问题,他们直接想重新创建他们的tabwidget

相关问题 更多 >

    热门问题