我创建了一个带有菜单栏和4个可停靠小部件的
当我运行代码时,会显示如下内容。
我可以使用以下代码来调整第一个Qdockwidget中内容的大小。
上述代码是写在子窗口小部件的
注意,我的停靠窗口仍然不会根据子部件调整大小。停靠窗口会扩展和增加。有人可能会问,Qdockwidgets可以通过
我一直在寻找相关问题。
https://dev59.com/JHE85IYBdhLWcg3wikO-
https://stackoverflow.com/questions/49606699/forcing-a-qdockwidget-to-behave-like-a-central-widget-when-it-comes-to-resizing?noredirect=1&lq=1
https://dev59.com/l4Tba4cB1Zd3GeqP1iLu
这些问题都没有解决我的问题。
我的代码启动可视化:
1- 当代码运行并显示在屏幕上时。
QMainWindow
。第一个停靠窗口包含多个选项卡,第二个是QPainter widget
,第三个是Matlabplot
,第四个是pdf报告
。当我运行代码时,会显示如下内容。
我想要变成以下这样。
每当屏幕运行时,我希望自动将屏幕分成四个小部件,并且我想要有选项卡来调整其大小以适应内容。
如果您有任何更好的小部件想法,欢迎提出。
代码更新
Qdockwidget的调整大小使得这篇文章变得更加重要。似乎Qt Qdockwidget调整大小一直是一个问题。我发现很难使用4个Qdockwidget编程我的Qmainwindow,其中dock会根据其内容(即子窗口)适合并调整大小。根据Qt文档,Qdockwidget会调整大小并考虑子窗口的大小。针对问题,我的主窗口有4个Qdockwidgets,我想让它们根据内容可调整大小。
到目前为止,我已尝试并使用以下大小函数。
self.sizeHint, self.minimumSize(), self.maximumSize() and self.setFixedSize(self.sizeHint()).
我可以使用以下代码来调整第一个Qdockwidget中内容的大小。
self.setFixedSize(self.sizeHint())
上述代码是写在子窗口小部件的
类widgets
中的。
但这并不足以使其工作,还需要按照以下代码运行和生效。 self.first.setMinimumSize(self.first.sizeHint())
self.grid.setMinimumSize(self.grid.sizeHint())
self.third.setMinimumSize(self.third.sizeHint())
self.adjustSize()
self.first.setMinimumSize(self.first.minimumSizeHint())
self.grid.setMinimumSize(self.grid.minimumSizeHint())
self.third.setMinimumSize(self.third.minimumSizeHint())
注意,我的停靠窗口仍然不会根据子部件调整大小。停靠窗口会扩展和增加。有人可能会问,Qdockwidgets可以通过
resizeDocks()
进行排列和控制。尝试使用此代码行,但仍无法获得所需的行为。我一直在寻找相关问题。
https://dev59.com/JHE85IYBdhLWcg3wikO-
https://stackoverflow.com/questions/49606699/forcing-a-qdockwidget-to-behave-like-a-central-widget-when-it-comes-to-resizing?noredirect=1&lq=1
https://dev59.com/l4Tba4cB1Zd3GeqP1iLu
这些问题都没有解决我的问题。
我的代码启动可视化:
1- 当代码运行并显示在屏幕上时。
2- 软件首次运行时期望的显示和要求。
3- 当用户在选项卡小部件之间切换时,希望调整大小以适应其内容,如下图所示。
4- 代码如下。
import sys, os
from PyQt5 import QtCore, QtWidgets, QtGui
from PyQt5.QtWidgets import QMainWindow, QLabel, QGridLayout, QWidget,
QDesktopWidget, QApplication, QAction, QFileDialog,QColorDialog
from PyQt5.QtWidgets import QPushButton, QMessageBox, QDockWidget,
QTabWidget, QVBoxLayout, QGroupBox, QHBoxLayout, QFrame, QSplitter
from PyQt5.QtWidgets import QTableWidget, QRadioButton, QListWidget,
QCheckBox, QTextEdit, QDialog, QSizePolicy
from PyQt5.QtCore import QSize, Qt, QFileInfo, QFile
from PyQt5.QtGui import QIcon, QKeySequence, QPainter, QPalette, QPen,
QBrush, QTextCursor, QFont
import matplotlib.pyplot as plt
#plt.style.use('ggplot')
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import seaborn as sns
iconroot = os.path.dirname(__file__)
class mywindow(QMainWindow):
def __init__(self):
super(mywindow, self).__init__()
self.setMinimumSize(QSize(1200,800))
self.setWindowTitle('My Graphic Window')
centralWidget = QWidget(self)
self.setCentralWidget(centralWidget)
gridLayout = QGridLayout(self)
centralWidget.setLayout(gridLayout)
qtRectangle = self.frameGeometry()
centerPoint = QDesktopWidget().availableGeometry().center()
qtRectangle.moveCenter(centerPoint)
self.move(qtRectangle.topLeft())
imageroot = QFileInfo(__file__).absolutePath()
# Greate new action
newaction = QAction(QIcon(imageroot +'/images/new.png'), '&New', self)
newaction.setShortcut('Ctrl+N')
newaction.setStatusTip('New document')
newaction.triggered.connect(self.newCall)
# Greate menu bar and add action
menubar = self.menuBar()
filemenu = menubar.addMenu('&Test')
filemenu.addAction(newaction)
# Get current screen geometry
self.Screen = QtWidgets.QDesktopWidget().screenGeometry()
print(self.Screen, self.Screen.height(), self.Screen.width())
# def createToolbar(self):
self.filetoolbar = self.addToolBar('File')
self.filetoolbar.addAction(newaction)
self.topleftdockwindow()
self.toprightdockwindow()
def newCall(self):
print('New')
# Greate dockable subwindow.
def topleftdockwindow(self):
topleftwindow = QDockWidget ('Info',self)
# Stick window to left or right
topleftwindow.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.addDockWidget(Qt.TopDockWidgetArea, topleftwindow)
topleftwindow.setWidget(createtabwidget())
topleftwindow.resize( topleftwindow.minimumSize() )
bottomleftwindow = QDockWidget("Matplot",self)
bottomleftwindow.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.addDockWidget(Qt.BottomDockWidgetArea, bottomleftwindow)
bottomleftwindow.setWidget(createplotwidget())
self.setDockNestingEnabled(True)
topleftwindow.resize( topleftwindow.minimumSize() )
self.splitDockWidget(topleftwindow, bottomleftwindow , Qt.Vertical)
#self.resizeDocks((topleftwindow, bottomleftwindow), (40,20),
#Qt.Horizontal)
# Greate topright dockwindow.
def toprightdockwindow(self):
toprightdock = QDockWidget ('Plot',self)
toprightdock = QDockWidget ('Plot',self)
toprightdock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.addDockWidget(Qt.TopDockWidgetArea, toprightdock)
#self.setDockOptions(self.AnimatedDocks | self.AllowNestedDocks)
toprightdock.setWidget(createpaintwidget())
toprightdock.setFloating( True )
bottomrightdock = QDockWidget("Technical report",self)
bottomrightdock.setAllowedAreas(Qt.LeftDockWidgetArea | Qt.RightDockWidgetArea)
self.addDockWidget(Qt.BottomDockWidgetArea, bottomrightdock)
bottomrightdock.setWidget(QtWidgets.QListWidget())
self.splitDockWidget(toprightdock, bottomrightdock, Qt.Vertical)
class createpaintwidget(QWidget):
def __init__(self):
super().__init__()
self.setBackgroundRole(QPalette.Base)
self.setAutoFillBackground(True)
self.sizeHint()
self.adjustSize()
def paintEvent(self, event):
self.pen = QPen()
self.brush = QBrush(Qt.gray,Qt.Dense7Pattern)
painter = QPainter(self)
painter.setPen(self.pen)
painter.setBrush(self.brush)
painter.drawRect(100,100,250,250)
painter.setBrush(QBrush())
painter.drawEllipse(400,100,200,200)
class createplotwidget(QWidget):
def __init__(self):
super().__init__()
self.initializewidget()
self.plot1()
self.setMaximumSize(self.sizeHint())
self.adjustSize()
def initializewidget(self):
self.setWindowTitle("Plotting M&N")
gridlayout = QGridLayout()
self.setLayout(gridlayout)
self.figure = plt.figure(figsize=(15,5))
self.canvas = FigureCanvas(self.figure)
self.toolbar = NavigationToolbar(self.canvas,self)
gridlayout.addWidget(self.canvas,1,0,1,2)
gridlayout.addWidget(self.toolbar,0,0,1,2)
def plot1(self):
# sns.set()
ax = self.figure.add_subplot(111)
x = [i for i in range(100)]
y = [i**2 for i in x]
ax.plot(x,y, 'b.-')
ax.set_title('Quadratic Plot')
self.canvas.draw()
class createtextdocument(QWidget):
def __init__(self):
super().__init__()
self.textedit()
def textedit(self):
self.textedit = QTextEdit()
self.cursor = self.textedit.textCursor()
class createtabwidget(QDialog):
def __init__(self):
super().__init__()
# Greate tabs in dockable window
tab = QTabWidget()
scroll = QScrollArea()
ncroll = QScrollArea()
mcroll = QScrollArea()
self.first = firsttabgeometry()
self.grid = Grid()
self.third = thirdtabloads()
scroll.setWidget(self.first)
ncroll.setWidget(self.grid)
mcroll.setWidget(self.third)
scroll.setWidgetResizable(True)
self.first.setMinimumSize(self.first.sizeHint())
self.grid.setMinimumSize(self.grid.sizeHint())
self.third.setMinimumSize(self.third.sizeHint())
self.adjustSize()
self.first.setMinimumSize(self.first.minimumSizeHint())
self.grid.setMinimumSize(self.grid.minimumSizeHint())
self.third.setMinimumSize(self.third.minimumSizeHint())
# Adding multiple tabslides
tab.addTab(self.first,'One')
tab.addTab(self.grid,'Two')
tab.addTab(self.third,'Three')
tab.setFont(QFont("Georgia",10,QFont.Normal))
vboxlayout = QVBoxLayout()
vboxlayout.addWidget(tab)
self.setLayout(vboxlayout)
class firsttabgeometry(QWidget):
def __init__(self):
super().__init__()
self.setFixedSize(self.sizeHint())
iconroot = QFileInfo(__file__).absolutePath()
font = QFont("Georgia",10,QFont.Normal)
# Add widget and buttons to tabs
sectiontypegroupbox = QGroupBox('&One',self)
sectiontypegroupbox.setFont(QFont("Georgia",10,QFont.Normal))
tab1button = QPushButton('')
tab1button.setIcon(QIcon(iconroot +'/images/circularcolumn'))
tab1button.setIconSize(QSize(60,60))
tab1button.clicked.connect(self.One)
squarebutton = QPushButton('')
squarebutton.setIcon(QIcon(iconroot +'/images/squarecolumn'))
squarebutton.setIconSize(QSize(60,60))
squarebutton.clicked.connect(self.Two)
wallbutton = QPushButton("")
wallbutton.setIcon(QIcon(iconroot +'/images/wall'))
wallbutton.setIconSize(QSize(60,60))
wallbutton.clicked.connect(self.Three)
circularlabel = QLabel(" One",self)
circularlabel.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
circularlabel.setFont(font)
sclabel = QLabel(" Two",self)
sclabel.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
sclabel.setFont(font)
walllabel = QLabel(" Three",self)
walllabel.setSizePolicy(QSizePolicy.Expanding,QSizePolicy.Expanding)
walllabel.setFont(font)
bottomgroupbox = QGroupBox("Group 2")
vboxlayout = QHBoxLayout()
vboxlayout.addStretch()
radiobutton2 = QRadioButton("Radio Button")
radiobutton3 = QRadioButton("Radio Button")
testbutton2 = QPushButton('Test Button 2')
vboxlayout.addWidget(radiobutton2)
vboxlayout.addWidget(radiobutton3)
vboxlayout.addWidget(testbutton2)
bottomgroupbox.setLayout(vboxlayout)
mainlayout = QGridLayout()
mainlayout.addWidget(tab1button,0,0)
mainlayout.addWidget(circularlabel,0,1)
mainlayout.addWidget(squarebutton,1,0)
mainlayout.addWidget(sclabel,1,1)
mainlayout.addWidget(wallbutton,2,0)
mainlayout.addWidget(walllabel,2,1)
mainlayout.setContentsMargins(200,50,50,50)
sectiontypegroupbox.setLayout(mainlayout)
gridlayout = QGridLayout()
gridlayout.addWidget(sectiontypegroupbox,1,0)
gridlayout.setContentsMargins(25,25,25,25)
self.setLayout(gridlayout)
def One(self):
print('One')
def Two(self):
print('Two')
def Three(self):
print('Three')
class FooWidget(QtWidgets.QWidget):
def __init__(self, path_icon, text, checked=False, parent=None):
super(FooWidget, self).__init__(parent)
lay = QtWidgets.QVBoxLayout(self)
pixmap = QtGui.QPixmap(os.path.join(iconroot, path_icon))
pixmap_label = QtWidgets.QLabel()
pixmap_label.resize(150, 150)
pixmap_label.setPixmap(pixmap.scaled(pixmap_label.size(), QtCore.Qt.KeepAspectRatio))
text_label = QtWidgets.QLabel(text)
checkbox = QtWidgets.QCheckBox(checked=checked)
lay.addWidget(pixmap_label)
lay.addWidget(text_label)
lay.addWidget(checkbox)
class Grid(QtWidgets.QWidget):
def __init__(self, parent=None):
super(Grid, self).__init__(parent)
self.setFixedSize(self.sizeHint())
font = QFont("Georgia",8,QFont.Normal)
lay = QtWidgets.QHBoxLayout(self)
icons = ["images/fixed-fixed.png",
"images/pinned-pinned.png",
"images/fixed-free.png",
"images/fixed-pinned.png"]
texts = ["Ley = 1.0 L\nLec = 1.0 L",
"Ley = 0.699 L\nLec = 0.699 L",
"Ley = 2.0 L\nLec = 2.0 L",
"Ley = 0.5 L\nLec = 0.5 L"]
for path_icon, text in zip(icons, texts):
w = FooWidget(os.path.join(iconroot, path_icon), text)
lay.addWidget(w)
class thirdtabloads(QtWidgets.QWidget):
def __init__(self, parent=None):
super(thirdtabloads, self).__init__(parent)
self.adjustSize()
table = loadtable()
add_button = QtWidgets.QPushButton("Add")
add_button.clicked.connect(table._addrow)
delete_button = QtWidgets.QPushButton("Delete")
delete_button.clicked.connect(table._removerow)
copy_button = QtWidgets.QPushButton("Copy")
copy_button.clicked.connect(table._copyrow)
button_layout = QtWidgets.QVBoxLayout()
button_layout.addWidget(add_button, alignment=QtCore.Qt.AlignBottom)
button_layout.addWidget(delete_button, alignment=QtCore.Qt.AlignTop)
button_layout.addWidget(copy_button, alignment=QtCore.Qt.AlignTop )
tablehbox = QtWidgets.QHBoxLayout()
tablehbox.setContentsMargins(10,10,10,10)
tablehbox.addWidget(table)
grid = QtWidgets.QGridLayout(self)
grid.addLayout(button_layout, 0, 1)
grid.addLayout(tablehbox, 0, 0)
def copy_widget(w):
if isinstance(w, QtWidgets.QWidget):
new_w = type(w)()
if isinstance(w, QtWidgets.QComboBox):
vals = [w.itemText(ix) for ix in range(w.count())]
new_w.addItems(vals)
return new_w
class loadtable(QtWidgets.QTableWidget):
def __init__(self, parent=None):
super(loadtable, self).__init__(1, 5, parent)
self.setFont(QtGui.QFont("Helvetica", 10, QtGui.QFont.Normal, italic=False))
headertitle = ("Load Name","N [kN]","My [kNm]","Mz [kNm]","Load Type")
self.setHorizontalHeaderLabels(headertitle)
self.verticalHeader().hide()
self.horizontalHeader().setHighlightSections(False)
self.horizontalHeader().setSectionResizeMode(QtWidgets.QHeaderView.Fixed)
self.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection)
self.setColumnWidth(0, 130)
combox_lay = QtWidgets.QComboBox(self)
combox_lay.addItems(["ULS","SLS"])
self.setCellWidget(0, 4, combox_lay)
self.cellChanged.connect(self._cellclicked)
@QtCore.pyqtSlot(int, int)
def _cellclicked(self, r, c):
it = self.item(r, c)
it.setTextAlignment(QtCore.Qt.AlignCenter)
@QtCore.pyqtSlot()
def _addrow(self):
rowcount = self.rowCount()
self.insertRow(rowcount)
combox_add = QtWidgets.QComboBox(self)
combox_add.addItems(["ULS","SLS"])
self.setCellWidget(rowcount, 4, combox_add)
@QtCore.pyqtSlot()
def _removerow(self):
if self.rowCount() > 0:
self.removeRow(self.rowCount()-1)
@QtCore.pyqtSlot()
def _copyrow(self):
r = self.currentRow()
if 0 <= r < self.rowCount():
cells = {"items": [], "widgets": []}
for i in range(self.columnCount()):
it = self.item(r, i)
if it:
cells["items"].append((i, it.clone()))
w = self.cellWidget(r, i)
if w:
cells["widgets"].append((i, copy_widget(w)))
self.copy(cells, r+1)
def copy(self, cells, r):
self.insertRow(r)
for i, it in cells["items"]:
self.setItem(r, i, it)
for i, w in cells["widgets"]:
self.setCellWidget(r, i, w)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
app.setStyle("Fusion")
mainWin = mywindow()
mainWin.show()
mainWin.showMaximized()
sys.exit(app.exec_())
我非常感激任何关于这个的帮助。