关于标签栏的奇怪问题.. 请帮我解决

0 投票
2 回答
2125 浏览
提问于 2025-04-15 17:10

我刚开始学习pyqt。当我在尝试使用标签栏时遇到了一些问题。为了简单明了,我想在第一个标签页显示一个按钮,在第二个标签页显示一个标签。以下是我做的事情:

from PyQt4 import QtGui    
class Ui_TabWidget(QtGui.QTabWidget):        
    def __init__(self,parent=None):
        QtGui.QTabWidget.__init__(self,parent)

        self.setObjectName("TabWidget")
        self.resize(400, 300)
        self.setWindowTitle(QtGui.QApplication.translate("TabWidget", "TabWidget", None, QtGui.QApplication.UnicodeUTF8))

        #Creating the tabbar
        self.tabBar=QtGui.QTabBar(self)

        #Adding the first tab
        self.tabBar.addTab("tab1")
        self.tabBar.setTabText(0,"TAB1")

        #The widget intended for tab1
        self.widgetforTab1=QtGui.QWidget()
        self.addTab(self.widgetforTab1,"")
        self.buttonForTab1=QtGui.QPushButton(self.widgetforTab1)
        self.buttonForTab1.setText("Button in Tab1")

        #Adding the second Tab
        self.tabBar.addTab("tab2")
        self.tabBar.setTabText(1,"TAB2")

        #The widget intended for tab2
        self.widgetForTab2=QtGui.QWidget()
        self.addTab(self.widgetForTab2,"")
        self.labelForTab2=QtGui.QLabel(self.widgetForTab2)
        self.labelForTab2.setText("Label in Tab2")

        #Adding the tabbar to the tabwidget
        self.setTabBar(self.tabBar)

        self.tabBar.setMovable(True)
        self.setCurrentIndex(0)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_TabWidget()
    ui.show()
    sys.exit(app.exec_())

在上面的程序中,针对第一个和第二个标签页的控件运行得很好。不过,我看不出控件和标签栏之间有什么联系。标签栏的标签是独立创建的,标签控件也是如此。它们都有自己的标签标题,但只有标签栏的标题被显示出来。如果我把索引设置为0,第一个标签就会和widgetForTab1一起显示。

在我的第二个程序中,控件和标签栏之间缺乏连接是导致问题的原因。

from PyQt4 import QtGui    
class Ui_TabWidget(QtGui.QTabWidget):
    def __init__(self,parent=None):
        QtGui.QTabWidget.__init__(self,parent)

        self.setObjectName("TabWidget")
        self.resize(400, 300)
        self.setWindowTitle(QtGui.QApplication.translate("TabWidget", "TabWidget", None, QtGui.QApplication.UnicodeUTF8))

        #Creating the tabbar
        self.tabBar=QtGui.QTabBar(self)

        #Adding the first tab
        self.tabBar.addTab("tab1")
        self.tabBar.setTabText(0,"TAB1")

        #Adding the second Tab
        self.tabBar.addTab("tab2")
        self.tabBar.setTabText(1,"TAB2")

        self.tabBar.setMovable(True)
        #Adding the tabbar to the tabwidget
        self.setTabBar(self.tabBar)

        #The widget intended for tab1
        self.widgetforTab1=QtGui.QWidget()
        self.addTab(self.widgetforTab1,"")
        self.buttonForTab1=QtGui.QPushButton(self.widgetforTab1)
        self.buttonForTab1.setText("Button in Tab1")

        #The widget intended for tab2
        self.widgetForTab2=QtGui.QWidget()
        self.addTab(self.widgetForTab2,"")
        self.labelForTab2=QtGui.QLabel(self.widgetForTab2)
        self.labelForTab2.setText("Label in Tab2")

        self.setCurrentIndex(0)

if __name__ == "__main__":
    import sys
    app = QtGui.QApplication(sys.argv)
    ui = Ui_TabWidget()
    ui.show()
    sys.exit(app.exec_())

第二个程序的输出结果很糟糕。我得到了四个标签,其中前两个标签没有文本,标签分别显示为“Tab1中的按钮”、“Tab2中的标签”、“Tab2中的标签”和“Tab2中的标签”。你能告诉我为什么会这样吗?我该怎么做才能解决这个问题?

2 个回答

1

你想要实现的功能,最好的办法是使用 QTabWidget。这个比 QTabBar 方便多了,99.99%的情况下都能满足你的需求。

下面是一个使用 QTabWidget 的经典示例:

from PyQt4.QtCore import *
from PyQt4.QtGui import *


class AppForm(QMainWindow):
    def __init__(self, parent=None):
        QMainWindow.__init__(self, parent)

        self.create_main_frame()       

    def create_main_frame(self):        
        tabs = QTabWidget()

        # Create first page
        page1 = QWidget()
        button1 = QPushButton('joy', page1)
        vbox1 = QVBoxLayout()
        vbox1.addWidget(button1)
        page1.setLayout(vbox1)

        # Create second page
        page2 = QWidget()
        label2 = QLabel('here I am')
        button2 = QPushButton('button on second page', page1)
        vbox2 = QVBoxLayout()
        vbox2.addWidget(label2)
        vbox2.addWidget(button2)
        page2.setLayout(vbox2)

        tabs.addTab(page1, 'First page')
        tabs.addTab(page2, 'Second page')

        self.setCentralWidget(tabs)



if __name__ == "__main__":
    import sys
    app = QApplication(sys.argv)
    form = AppForm()
    form.show()
    app.exec_()
2

我知道这个问题已经问了一段时间了,但我注意到你对之前回答的回复是,你需要能够通过样式表来定制标签页。其实在使用QTabWidget的时候,这也是可以做到的!因为所有的QWidget都有一个叫做 setStyleSheet() 的功能,而QTabWidget底层使用了QTabBar,所以你几乎可以直接使用相同的样式表。比如,这里有一个样式表,我用它来改变我基于PyQt/PySide的网页浏览器中标签页的外观,这个浏览器使用了QTabWidget:

QTabWidget::tab-bar {
    left: 2px; /* move to the right by 2px */
}

/* Style the tab using the tab sub-control. Note that
 * it reads QTabBar _not_ QTabWidget
 */
QTabBar::tab {
    min-width: 24px;
    max-width: 280px;
    padding: 2px 5px;
    font-size: .85em;
}

QTabBar::tab:!selected {
    margin-top: 2px; /* make non-selected tabs look smaller */
}

/* make use of negative margins for overlapping tabs */
QTabBar::tab:selected {
    /* expand/overlap to the left and right by 4px */
    margin-left: -2px;
    margin-right: -2px;
}

QTabBar::tab:first:selected {
    /* first selected tab has nothing to overlap with on the left */
    margin-left: 0;
}

QTabBar::tab:last:selected {
    /* last selected tab has nothing to overlap with on the right */
    margin-right: 0;
}

QTabBar::tab:only-one {
    /* if there is only one tab, we don't want overlapping margins */
    margin-left: 0;
    margin-right: 0;
}

这个样式表确实需要一些调整,但它展示了在QTabWidget上应用样式时可以实现的效果。你还可以查看官方的Qt样式表示例页面上的 QTabBar和QTabWidget部分

撰写回答