Установка начального размера QTabWidget в приложении QSplitter PyQt
У меня есть вертикальный сплиттер с QTabWidget вверху и виджетом QPlainTextEdit внизу (используется как окно регистрации). В реальном приложении вкладки заполнены QWidgets, содержащими холст matplotlib и QFrame с некоторыми элементами управления:
QSplitter
QPlainTextEdit
QVBoxLayout
QTabWidget
QWidget
QVBoxLayout
FigureCanvas (QSizePolicy.Expanding, QSizePolicy.Expanding)
QFrame (optional)
Я хотел бы, чтобы приложение запускалось с хорошим вертикальным соотношением, скажем, 4:1 между вкладками и окном ведения журнала. Однако, используя mysplitter.setStretchFactor(4,1)
здесь не работает как sizeHint()
только QTabWidget (4,4), вызывая QPlainTextEdit с sizeHint() = (256,192)
сожрать почти все доступное вертикальное пространство. В качестве обходного пути в настоящее время я устанавливаю фиксированную высоту для QPlainTextWidget, но я знаю, что этот виджет не является виновником.
Я думаю, что мне нужно поиграть с sizePolicies или с макетом / размерами отдельных вкладок, но пока я не добился успеха. Я прикрепил MWE, полный код доступен по адресу https://github.com/chipmuenk/pyFDA/blob/master/pyfda/pyfdax.py:
# -*- coding: utf-8 -*-
from __future__ import print_function
from PyQt5.QtWidgets import (QWidget, QTabWidget, QPlainTextEdit, QSplitter,
QMainWindow, QVBoxLayout, QApplication)
from PyQt5.QtGui import QFontMetrics
from PyQt5 import QtCore
#------------------------------------------------------------------------------
class TabWidgets(QTabWidget):
def __init__(self, parent):
super(TabWidgets, self).__init__(parent)
self.wdg1 = QWidget(self)
self.wdg2 = QWidget(self)
self._construct_UI()
#------------------------------------------------------------------------------
def _construct_UI(self):
""" Initialize UI with tabbed subplots """
self.tabWidget = QTabWidget(self)
self.tabWidget.addTab(self.wdg1, 'Wdg 1')
self.tabWidget.addTab(self.wdg2, 'Wdg 2')
layVMain = QVBoxLayout()
layVMain.addWidget(self.tabWidget)
self.setLayout(layVMain)
# When user has switched the tab, call self.current_tab_redraw
self.tabWidget.currentChanged.connect(self.current_tab_redraw)
#------------------------------------------------------------------------------
def current_tab_redraw(self):
pass
#self.tabWidget.currentWidget().resize()
class MWin(QMainWindow):
"""
Main window consisting of a tabbed widget and a status window.
QMainWindow is used as it understands GUI elements like central widget
"""
def __init__(self, parent=None):
super(QMainWindow,self).__init__()
#---------------------------------------------------------------
statusWin = QPlainTextEdit(self) # status window
tabWin = TabWidgets(self) # tabbed window
print('size status win: {0}'.format(statusWin.sizeHint()))
print('size_tab win: {0}'.format(tabWin.sizeHint()))
mSize = QFontMetrics(statusWin.font())
rowHt = mSize.lineSpacing()
# fixed height for statusWin needed as the sizeHint of tabWin is very small
statusWin.setFixedHeight(4*rowHt+4)
# add status window underneath plot Tab Widgets:
spltVMain = QSplitter(QtCore.Qt.Vertical)
spltVMain.addWidget(tabWin)
spltVMain.addWidget(statusWin)
# relative initial sizes of subwidgets, this doesn't work here
spltVMain.setStretchFactor(4,1)
spltVMain.setFocus()
# make spltVMain occupy the main area of QMainWindow and set inheritance
self.setCentralWidget(spltVMain)
#----------------------------------------------------------------------------
def main():
import sys
app = QApplication(sys.argv)
mainw = MWin(None)
mainw.resize(300,400)
app.setActiveWindow(mainw)
mainw.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
1 ответ
Я нашел простой обходной путь: установка сплиттера в абсолютных единицах вместо отношения делает работу. Указывает общую высоту виджета сплиттера, заставляет решение работать с различными разрешениями и т. Д. В приведенном ниже фрагменте кода показаны обновленные __init__()
часть:
def __init__(self, parent=None):
super(QMainWindow,self).__init__()
#---------------------------------------------------------------
statusWin = QPlainTextEdit(self) # status window
tabWin = TabWidgets(self) # tabbed window
print('size status win: {0}'.format(statusWin.sizeHint()))
print('size_tab win: {0}'.format(tabWin.sizeHint()))
# fixed height for statusWin no longer needed here
# mSize = QFontMetrics(statusWin.font())
# rowHt = mSize.lineSpacing()
# statusWin.setFixedHeight(4*rowHt+4)
# add status window underneath plot Tab Widgets:
spltVMain = QSplitter(QtCore.Qt.Vertical)
spltVMain.addWidget(tabWin)
spltVMain.addWidget(statusWin)
# relative initial sizes of subwidgets, this doesn't work here
# spltVMain.setStretchFactor(4,1)
# Use absolute values instead:
spltVMain.setSizes([spltVMain.size().height() * 0.8,
spltVMain.size().height() * 0.2])
spltVMain.setFocus()
# make spltVMain occupy the main area of QMainWindow and set inheritance
self.setCentralWidget(spltVMain)
#-----------------------------------------------------------------------