【问题标题】:Difficulty Getting PyQt GUI Elements to Correctly Show难以正确显示 PyQt GUI 元素
【发布时间】:2019-09-10 05:13:27
【问题描述】:

这里是新的 Python 程序员。我正在尝试制作一个简单的 GUI,但无法显示其中一个 PyQt 元素。也许这里有人可以为我指出正确的方向并给出一些通用代码cmets。别担心。我知道我的代码可能很糟糕。我们都必须从某个地方开始。

我有一个由 HBoxLayout 中的两个小部件组成的 GUI。一个小部件是简单的 PushButton,另一个是自定义 ControlWidget。我可以让这些显示得很好(尽管有对齐问题)。在 ControlWidget 上,我有一个带有一些标签、组合框和子类 QTextBrowser(调试器)的 GridLayout。这是我不能出现的。

诚然,我不确定该怎么做。继承错了吗?我需要将其他东西传递给较低的班级吗?等等

MainGUI.py

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import *
from PyQt5.QtCore import *

from ControlWidget import ControlWidget
# from MenuBar import MenuBar
from Debugger import Debugger

# Main 
class TopWindow(QMainWindow):
    def __init__(self):
        super(TopWindow, self).__init__()
        self.setWindowTitle('Test GUI')
        self.setGeometry(0, 0, 800, 600)
        self.setMaximumSize(1024, 768)
        self.initUI()

    def initUI(self):
        # MenuBar.initMenuBar(self)
        centralWidget = QWidget(self)
        self.setCentralWidget(centralWidget)
        hLayout = QHBoxLayout(centralWidget)
        pushButton = QPushButton("Button A")
        hLayout.addWidget(pushButton)
        hLayout.addWidget(ControlWidget())

        self.show()

# Program Entry Point        
if __name__ == '__main__':
    applicationInstance = QApplication(sys.argv)
    ex = TopWindow()
    sys.exit(applicationInstance.exec_())

ControlWidget.py

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * 
from PyQt5.QtCore import *

from Debugger import Debugger

class ControlWidget(QWidget):
    def __init__(self, parent=None):
        super(ControlWidget, self).__init__(parent)
        self.left = 100
        self.top = 100
        self.width = 320
        self.height = 100
        self.numClicks = 0
        self.setMaximumWidth(240) 
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Fixed)
        self.initUI()

    def initUI(self):
        self.setGeometry(self.left, self.top, self.width, self.height)

        self.createGridLayout()

    def createGridLayout(self):
        # Create Grid Layout
        layout = QGridLayout()
        self.setLayout(layout)
        layout.setColumnStretch(0, 2)
        layout.setColumnStretch(1, 3)
        layout.setColumnStretch(2, 1)

        # Instantiate Labels
        labelA = QLabel()
        labelB = QLabel()
        labelC = QLabel()
        labelD = QLabel()
        labelE = QLabel()
        labelF = QLabel()
        self.labelFa = QLabel()
        labelA.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        labelB.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        labelC.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        labelD.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        labelE.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        labelF.setAlignment(Qt.AlignRight | Qt.AlignVCenter)
        self.labelFa.setAlignment(Qt.AlignCenter | Qt.AlignVCenter)
        labelA.setText('ABCD: ')
        labelB.setText('BCDE: ')
        labelC.setText('CDEF: ')
        labelD.setText('DEFG: ')
        labelE.setText('EFGH: ')
        labelF.setText('FGHI: ')

        # Instantiate Combo Boxes
        comboBoxA = QComboBox()
        comboBoxB = QComboBox()
        comboBoxC = QComboBox()
        comboBoxD = QComboBox()
        comboBoxE = QComboBox()
        comboBoxA.addItems(["A", "B", "C", "D"])
        comboBoxB.addItems(["B", "C", "D", "E"])
        comboBoxC.addItems(["C", "D", "E", "F"])
        comboBoxD.addItems(["D", "E", "F", "G"])
        comboBoxE.addItems(["E", "F", "G", "H"])

        # Instantiate Push Buttons
        pushButtonF = QPushButton()
        pushButtonF.setText('Set Value')

        # Spacer
        spacer = QSpacerItem(10, 30, QSizePolicy.Fixed, QSizePolicy.Fixed)

        # Message Box
        labelDebug = QLabel()
        labelDebug.setText("Debug")
        labelDebug.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
        debug = Debugger(self) # DOES NOT WORK

        # Add to Grid Layout (item, row, column, rowspan, colspan)
        layout.addWidget(labelA, 0, 0)
        layout.addWidget(labelB, 1, 0)
        layout.addWidget(labelC, 2, 0)
        layout.addWidget(labelD, 3, 0)
        layout.addWidget(labelE, 4, 0)
        layout.addWidget(labelF, 5, 0)
        layout.addWidget(comboBoxA, 0, 1, 1, 2)
        layout.addWidget(comboBoxB, 1, 1, 1, 2)
        layout.addWidget(comboBoxC, 2, 1, 1, 2)
        layout.addWidget(comboBoxD, 3, 1, 1, 2)
        layout.addWidget(comboBoxE, 4, 1, 1, 2)
        layout.addWidget(pushButtonF, 5, 1, 1, 1)
        layout.addWidget(self.labelFa, 5, 2, 1, 1)
        layout.addItem(spacer, 6, 0, 1, 3)
        layout.addWidget(labelDebug, 7, 0)
        layout.addWidget(debug, 8, 0)

        # Hook Up ComboBox Signals to Handlers
        comboBoxA.currentIndexChanged.connect(self.comboBoxAHandler)

        # Hook Up PushButton Signals to Handlers
        pushButtonF.clicked.connect(self.pushButtonFHandler)

        #self.horizontalGroupBox.setLayout(layout)

    def comboBoxAHandler(self, i):
        print('Combo Box A Selection Changed to {0}'.format(i))
        #Debugger.write(self, 'Combo Box A Selection Changed')

    def pushButtonFHandler(self):
        print('Push Button F Clicked')
        self.numClicks = self.numClicks + 1
        self.labelFa.setText(str(self.numClicks))

调试器.py

import sys
from PyQt5.QtWidgets import *
from PyQt5.QtGui import * 
from PyQt5.QtCore import *

class Debugger(QWidget):
    def __init__(self, parent=None):
        super(Debugger, self).__init__(parent)
        self.setMaximumWidth(240)
        self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
        self.createTextBrowser()

    def createTextBrowser(self):
        self.textBrowser = QTextBrowser()
        self.textBrowser.setReadOnly(True)

    def write(self, text):
        self.textBrowser.append("• " + text)

我遗漏或做错了什么简单的事情?

【问题讨论】:

    标签: python pyqt pyqt5


    【解决方案1】:

    您有 2 个错误:

    • 您在调试器中使用的不是继承,而是组合。

    • 如果要在同一类的其他方法中使用变量,则必须使该变量成为该类的成员。

    综合以上,解决办法是:

    Debugger.py

    import sys
    from PyQt5.QtWidgets import QTextBrowser, QSizePolicy
    
    class Debugger(QTextBrowser):
        def __init__(self, parent=None):
            super(Debugger, self).__init__(parent)
            self.setMaximumWidth(240)
            self.setSizePolicy(QSizePolicy.Fixed, QSizePolicy.Expanding)
            self.setReadOnly(True)
    
        def write(self, text):
            self.append("• " + text)
    

    ControlWidget.py

    
    # ...
    class ControlWidget(QWidget):
        # ...
    
        def initUI(self):
            # ...
    
            # Message Box
            labelDebug = QLabel()
            labelDebug.setText("Debug")
            labelDebug.setAlignment(Qt.AlignLeft | Qt.AlignVCenter)
            self.debug = Debugger() # <---
    
            # ...
            layout.addWidget(labelDebug, 7, 0)
            layout.addWidget(self.debug, 8, 0) # <---
    
            # Hook Up ComboBox Signals to Handlers
            # ...
    
        def comboBoxAHandler(self, i):
            print('Combo Box A Selection Changed to {0}'.format(i))
            self.debug.write('Combo Box A Selection Changed') # <---
        # ...
    

    我建议阅读以下出版物,以便您了解继承(is-a)和组合(has-a)之间的区别:

    【讨论】:

    • 感谢您的建议。该解决方案解决了这个问题。我一定会去阅读继承与组合。
    【解决方案2】:

    我的猜测是,这与您的 textbrowser 对象没有父对象有关,而且您从未明确告诉过 .show()。 通常,当一个部件有父部件时,调用父部件的 show 方法也会显示子部件。由于您的 textbrowser 对象没有父对象,因此替代方法是显式显示该对象,但您也没有这样做。

    在您的 TopWindow 类的 initUI 方法中,您调用 self.show()。这是显示所有父母的孩子的实际调用(父母是自我,窗口)。这个单一的调用正确地显示了您的其他小部件,因为您明确地将主窗口指定为它们的父窗口,但它没有显示您的文本浏览器,因为您没有给它一个父窗口。 (注意,因为您的调试器类使用的是组合而不是继承,所以您确实为调试器提供了一个父级(这是一个 QWidget),但实际的 QTextBrowser 对象没有父级)

    【讨论】:

      猜你喜欢
      • 2017-07-25
      • 1970-01-01
      • 2020-05-11
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-05-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多