关于标签栏的奇怪问题.. 请帮我解决
我刚开始学习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 个回答
你想要实现的功能,最好的办法是使用 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_()
我知道这个问题已经问了一段时间了,但我注意到你对之前回答的回复是,你需要能够通过样式表来定制标签页。其实在使用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部分。