在QMainWindow中放置一个小部件,如何定位而不是setCentralWidget

2022-01-12 00:00:00 python pyqt pyqt5

问题描述

我正在使用 QGridLayout,通过使用 setCentralWidget 函数,行和列 (0,0) 从窗口的中心开始,留下很多空白空间.

I'm using QGridLayout, and by using the setCentralWidget function, the row and column (0,0) start in the center of the window which leaves a lot of empty space.

如何让它居中但从窗口顶部开始而不是在中间?

How can I get it centered but beginning from the top of the window and not in the middle?

我对 Qt 还很陌生,想知道我是否处理错了?我应该改为为 QWidget 创建一个新类吗?

I'm pretty new to Qt, and was wondering if I'm handling it all wrong? Should I instead make a new class for QWidget?

class App(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'Data visualizing'
        self.left = 50
        self.top = 50
        self.width = 300
        self.height = 100
        self.initUI()

    def initUI(self):
        self.central_widget = QWidget()
        self.setCentralWidget(self.central_widget)

        # Create textbox
        self.textbox = QLineEdit(self)
        self.textbox.setReadOnly(True)

        # Create textbox 2
        self.textbox2 = QLineEdit(self)
        self.textbox2.setReadOnly(True)

        # Create button
        self.button = QPushButton('Load file 1', self)
        self.button.setToolTip('Click here to browse for the first data file')
        self.button.clicked.connect(self.on_click)

        # Create button 2
        self.button2 = QPushButton('Load file 2', self)
        self.button2.setToolTip('Click here to browse for the first data file')
        self.button2.clicked.connect(self.on_click)

        grid = QGridLayout()

        grid.addWidget(self.textbox, 0, 0, 0, 3)
        grid.addWidget(self.textbox2, 0, 3, 0, 3)
        grid.addWidget(self.button, 1, 1, 1, 1)
        grid.addWidget(self.button2, 1, 4, 1, 1)

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.centralWidget().setLayout(grid)
        self.show()

    def openFileNameDialog(self):
        options = QFileDialog.Options()
        options |= QFileDialog.DontUseNativeDialog
        fileName, _ = QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
                                                  "All Files (*);;Comma seperated files (*.csv)", options=options)
        if fileName:
            self.textbox.setText(fileName)
            print(fileName)

    @pyqtSlot()
    def on_click(self):
        self.openFileNameDialog()
        print('PyQt5 button click')

if __name__ == '__main__':
    app = QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()


解决方案

你必须在第2行建立一个Stretch,但在此之前你必须更正rowSpan:

You have to establish a Stretch in row 2, but before that you must correct the rowSpan in:

grid.addWidget(self.textbox, 0, 0, 0, 3)
grid.addWidget(self.textbox2, 0, 3, 0, 3)

为了理解,让我们回顾一下文档:

To understand, let's review the docs:

void QGridLayout::addWidget(QWidget *widget, int fromRow, intfromColumn, int rowSpan, int columnSpan, Qt::Alignment 对齐 =...)

这是一个重载函数.

此版本将给定的小部件添加到单元格网格中,跨越多个行/列.单元格将从 fromRow 开始,fromColumn 跨越rowSpan 行和 columnSpan 列.小部件将具有给定的对齐.

This version adds the given widget to the cell grid, spanning multiple rows/columns. The cell will start at fromRow, fromColumn spanning rowSpan rows and columnSpan columns. The widget will have the given alignment.

如果 rowSpan 和/或 columnSpan 为 -1,则小部件将分别延伸到底部和/或右边缘.

If rowSpan and/or columnSpan is -1, then the widget will extend to the bottom and/or right edge, respectively.

也就是说,rowSpan 表示小部件将占用多少行,但您将其指示为 0,因此布局将不再处理大小而仅处理位置,您必须将其更改为 1.

That is, the rowSpan indicates how many rows the widget will occupy, but you are indicating it to 0 so the size will no longer be handled by the layout but only the position, you must change it to 1.

import sys
from PyQt5 import QtCore, QtGui, QtWidgets


class App(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = 'Data visualizing'
        self.left, self.top, self.width, self.height = 50, 50, 300, 100
        self.initUI()

    def initUI(self):
        self.central_widget = QtWidgets.QWidget()
        self.setCentralWidget(self.central_widget)

        # Create textboxs
        self.textbox = QtWidgets.QLineEdit(readOnly=True)
        self.textbox2 = QtWidgets.QLineEdit(readOnly=True)

        # Create buttons
        self.button = QtWidgets.QPushButton('Load file 1', 
            toolTip = 'Click here to browse for the first data file')
        self.button.clicked.connect(self.on_click)
        self.button2 = QtWidgets.QPushButton('Load file 2',
            toolTip = 'Click here to browse for the first data file')
        self.button2.clicked.connect(self.on_click)

        grid = QtWidgets.QGridLayout(self.centralWidget())

        grid.addWidget(self.textbox, 0, 0, 1, 3)
        grid.addWidget(self.textbox2, 0, 3, 1, 3)
        grid.addWidget(self.button, 1, 1, 1, 1)
        grid.addWidget(self.button2, 1, 4, 1, 1)
        grid.setRowStretch(2, 1)

        self.setWindowTitle(self.title)
        self.setGeometry(self.left, self.top, self.width, self.height)
        self.show()

    def openFileNameDialog(self):
        options = QtWidgets.QFileDialog.Options()
        options |= QtWidgets.QFileDialog.DontUseNativeDialog
        fileName, _ = QtWidgets.QFileDialog.getOpenFileName(self, "QFileDialog.getOpenFileName()", "",
                                                  "All Files (*);;Comma seperated files (*.csv)", options=options)
        if fileName:
            self.textbox.setText(fileName)
            print(fileName)

    @QtCore.pyqtSlot()
    def on_click(self):
        self.openFileNameDialog()
        print('PyQt5 button click')

if __name__ == '__main__':
    app = QtWidgets.QApplication(sys.argv)
    ex = App()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

相关文章