PyQt5 QWidget不填充父

Posted

技术标签:

【中文标题】PyQt5 QWidget不填充父【英文标题】:PyQt5 QWidget not filling parent 【发布时间】:2018-02-07 13:29:31 【问题描述】:

我正在 PyQt5 中创建一个代码编辑器。我在中心小部件中使用 QGridLayout 并从那里构建 UI。我面临的问题是 QPlainTextEdit 和菜单没有填充中心小部件上的可用空间。我尝试将大小策略设置为扩展并尝试调整 QGridLayout 的拉伸参数。

我在 python 2.7 和 PyQt 5 中运行代码。使用 PyCharm IDE。

main.py

import os
import sys
from PyQt5.QtWidgets import QMainWindow, QApplication, QAction

from PyQt5.QtGui import QIcon

import UI

versao = '3.0.0'


class Principal(QMainWindow):

    def __init__(self):
        super(Principal, self).__init__()

        self.acao_novo = 0
        self.acao_abrir = 0
        self.acao_exemplos = 0
        self.acao_sair = 0
        self.acao_salvar = 0
        self.acao_salvar_como = 0
        self.acao_comentar_linha = 0
        self.acao_achar = 0
        self.acao_achar_e_substituir = 0
        self.acao_ir_para_linha = 0
        self.acao_placa = 0
        self.acao_porta = 0
        self.acao_lingua = 0
        self.acao_monitor_serial = 0
        self.acao_verificar = 0
        self.acao_verificar_e_carregar = 0

        self.init_ui()

    def init_ui(self):

        self.setCentralWidget(UI.Centro())

        self.setGeometry(300, 300, 500, 550)
        self.setWindowTitle('Br.ino ' + versao)
        self.setWindowIcon(QIcon(os.path.join('recursos', 'logo.png')))
        self.show()

def main():
    app = QApplication(sys.argv)
    principal = Principal()
    app.setStyleSheet("""QMainWindow 
                             background: '#252525';
                         
                         QMenu
                             background: '#252525';
                         
                         QMenu::item 
                             background: '#252525';
                          
                         QMenu::item:selected
                             background: '#101010';
                         
                         QMenuBar 
                             background: '#252525';
                         
                         QMenuBar::item 
                             background: '#252525';
                          
                         QMenuBar::item:selected
                             background: '#101010';
                         
                         QPlainTextEdit
                             background: '#252525';
                             border: None;
                             border-radius: 6px;
                             color: '#efefef';
                             selection-background-color: '#454545';
                         """)
    sys.exit(app.exec_())


if __name__ == '__main__':
    main() 

UI.py

from PyQt5.QtWidgets import (QWidget, QGridLayout, QPlainTextEdit, QVBoxLayout, QSpacerItem, QSizePolicy, QAbstractButton)
import os
from PyQt5.QtGui import QPixmap, QPainter
from PyQt5.QtCore import QSize


class Centro(QWidget):

    def __init__(self):
        super(Centro, self).__init__()
        self.layout = 0

        self.init_ui()

    def init_ui(self):
        layout = QGridLayout(self)
        layout.setRowStretch(0, 7.5)
        layout.setRowStretch(1, 2.5)
        layout.setColumnStretch(0, 1)
        layout.setColumnStretch(1, 5)
        menu = Menu.Menu()
        layout.addWidget(menu, 0, 0, 1, 0)
        layout.setSpacing(10)
        layout.setContentsMargins(0, 0, 0, 0)

        container = QWidget(self)
        container.setStyleSheet("background:#252525")
        editor = QPlainTextEdit(container)
        layout.addWidget(container, 0, 1, 9, 9)

        container_log = QWidget(self)
        log = QPlainTextEdit(container_log)
        log.setStyleSheet("background:#000000")
        log.setDisabled(True)
        layout.addWidget(container_log, 1, 1, 1, 8)

        self.show()


class Menu(QWidget):

    def __init__(self):
        super(Menu, self).__init__()
        self.layout = 0

        self.init_ui()

    def init_ui(self):
        container = QWidget(self)
        container.setFixedWidth(60)
        layout = QVBoxLayout(container)
        container.setStyleSheet("background-color: '#5cb50d';")

        btn_compilar = botaoImagem(QPixmap(os.path.join('recursos', 'compilarFoco.png')), self)
        btn_compilar_e_carregar = botaoImagem(QPixmap(os.path.join('recursos', 'carregarFoco.png')), self)
        btn_novo = botaoImagem(QPixmap(os.path.join('recursos', 'novoArquivoFoco.png')), self)
        btn_abrir = botaoImagem(QPixmap(os.path.join('recursos', 'abrirPastaFoco.png')), self)
        btn_salvar = botaoImagem(QPixmap(os.path.join('recursos', 'salvarFoco.png')), self)
        btn_monitor_serial = botaoImagem(QPixmap(os.path.join('recursos', 'monitorSerialFoco.png')), self)
        btn_monitor_serial.setFixedSize(50, 50)

        layout.setContentsMargins(5, 5, 5, 0)
        espacador_vertical = QSpacerItem(0, 500000000, QSizePolicy.Minimum, QSizePolicy.Expanding)
        layout.addWidget(btn_compilar)
        layout.addWidget(btn_compilar_e_carregar)
        layout.addWidget(btn_novo)
        layout.addWidget(btn_abrir)
        layout.addWidget(btn_salvar)
        layout.addWidget(btn_monitor_serial)
        layout.addItem(espacador_vertical)

        self.show()


class botaoImagem(QAbstractButton):
    def __init__(self, pixmap, parent=None):
        super(botaoImagem, self).__init__(parent)
        self.pixmap = pixmap

    def paintEvent(self, event):
        painter = QPainter(self)
        painter.drawPixmap(event.rect(), self.pixmap)

    def sizeHint(self):
        return QSize(50, 63)

预期结果如下(此截图是以前的版本,用Java开发,因此它包含一些尚未实现的功能):

【问题讨论】:

什么是Menu.Menu() 可能不相关,但是...layout.addWidget(menu, 0, 0, 1, 0) 指定 menu 应该跨越 列。 你能展示一张你想要得到什么的图片吗? Menu 是一个类,Menu.Menu() 是构造函数。其实menu占据了第0列我会尽快添加图片 【参考方案1】:

不要创建“容器”小部件,它们不是必需的。将小部件直接添加到您的布局中。

您的问题是,虽然您正在设置布局,但您将容器小部件添加到父 没有 布局,因此 容器 不会缩放。

即不是

container = QWidget(self)
container.setStyleSheet("background:#252525")
editor = QPlainTextEdit(container)
layout.addWidget(container, 0, 1, 9, 9)

editor = QPlainTextEdit(self)
editor.setStyleSheet("background:#252525")
layout.addWidget(editor, 0, 1, 9, 9)

更新:这是Menu的操作方法

layout = QVBoxLayout(self)
self.setFixedWidth(60)
self.setStyleSheet("background-color: '#5cb50d';")

【讨论】:

我应该如何使用 Menu 类?如何将父级添加到 init 适用于水平展开,但菜单不会垂直展开 查看我的更新答案。如果您已将其正确添加到布局中,则它应该垂直扩展。如果您的预期行为是让按钮展开以填充可用空间,那么您需要删除Menu 中的QSpacerItem。还要确保你已经解决了@G.M. 上面指出的问题。

以上是关于PyQt5 QWidget不填充父的主要内容,如果未能解决你的问题,请参考以下文章

Pyqt5_QWidget

PyQt5 - QLabel 填充无法按预期工作

setParent 的 PyQt5 行为以显示没有布局的 QWidget

PyQt5 中的 QWebEngineView 和 QWidget

PyQt5 样式表用于 QWidget 的孩子更改 QWidget

QWidget父窗口设置的背景色怎么不影响子窗口