Python 3.x 如何在PyQt5中的QMainWindow上设置自定义小部件

Python 3.x 如何在PyQt5中的QMainWindow上设置自定义小部件,python-3.x,pyqt5,custom-widgets,Python 3.x,Pyqt5,Custom Widgets,我试图在pyQT主窗口上显示一个自定义小部件,但由于某些原因,我得到了两个窗口,而不是功能年中定义的自定义小部件,即对话框_01(主窗口)中显示的可检查组合框。下面是我的代码。如果有人有任何指示或文件,我可以看看,谢谢 import sys from PyQt5 import QtGui, QtCore from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageB

我试图在pyQT主窗口上显示一个自定义小部件,但由于某些原因,我得到了两个窗口,而不是功能年中定义的自定义小部件,即对话框_01(主窗口)中显示的可检查组合框。下面是我的代码。如果有人有任何指示或文件,我可以看看,谢谢

import sys
from PyQt5 import QtGui, QtCore
from PyQt5.QtWidgets import QApplication, QMainWindow, QMenu, QVBoxLayout, QSizePolicy, QMessageBox, QWidget, QPushButton
from PyQt5 import QtWidgets
class CheckableComboBox(QtWidgets.QComboBox):
    closedPopup = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(CheckableComboBox, self).__init__(parent)
        self.setView(QtWidgets.QListView(self))
        self.view().pressed.connect(self.handleItemPressed)
        self.setModel(QtGui.QStandardItemModel(self))

        firstItem = QtGui.QStandardItem("Select Years")
        firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
        firstItem.setSelectable(False)
        self.model().appendRow(firstItem)

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.checkState() == QtCore.Qt.Checked:
            item.setCheckState(QtCore.Qt.Unchecked)
        else:
            item.setCheckState(QtCore.Qt.Checked)

    def checkedItems(self):
        l = []
        for i in range(self.model().rowCount()):
            it = self.model().item(i)
            if it.checkState() == QtCore.Qt.Checked:
                l.append(it.text())
        return l

    def hidePopup(self):
        self.closedPopup.emit()
        super(CheckableComboBox, self).hidePopup()
        QtCore.QTimer.singleShot(0, lambda: self.setCurrentIndex(0))
class Dialog_01(QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = "Title"  
        self.top = 100        
        self.left = 100        
        self.width = 800      
        self.height = 500
        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        self.setGeometry(self.top, self.left, self.width, self.height)
        self.years()
        self.location()
        self.MaxYears()

        self.layout = QtWidgets.QVBoxLayout(self)
        self.listWidget = self.comboBoxv
        self.layout.addWidget(self.listWidget)
        self.listWidget.show()
    def years(self):
        label0 = QLabel('Years', self)
        label0.move(50,50)
        label0.setGeometry(50,50,500,20)

        years = ["2017", "2018", "2019", "2020", "2021", "2022"]
        self.comboBoxv = CheckableComboBox()
        for i, area in enumerate(years):
            item = QtGui.QStandardItem(area)
            item.setCheckable(True)
            item.setCheckState(QtCore.Qt.Unchecked)
            self.comboBoxv.model().appendRow(item)        
        self.layout = QtWidgets.QVBoxLayout(self)
        self.setLayout(self.layout)
        self.listWidget = self.comboBoxv
        self.layout.addWidget(self.listWidget)
        self.listWidget.move(300, 50)


    @QtCore.pyqtSlot()
    def on_closedPopup(self):
        print(len(self.comboBoxv.checkedItems()))


    def location(self):  
        label1 = QLabel('Location', self)
        label1.move(50,150)
        label1.setGeometry(50,150,500,20)
        comboBox1 = QComboBox(self)
        for i in range(1,15):
            comboBox1.addItem("LOCATION %i" % i)
        comboBox1.move(300, 150)
        self.locationDrop=comboBox1
    def MaxYears(self):
        label2 = QLabel('Maximum Years', self)
        label2.move(50,250)
        label2.setGeometry(50,250,500,20)
        comboBox2 = QComboBox(self)
        for i in range(1, 10):
            comboBox2.addItem(str(i))
        comboBox2.move(300, 250)
        self.maxyearsDrop=comboBox2

if __name__ == '__main__':

    if not QApplication.instance():
        App = QApplication(sys.argv)
    else:
        App = QApplication.instance()
    ui = Dialog_01()
    ui.show()
    sys.exit(App.exec_())

您必须了解,编程并不是在放置无意义的代码,例如:您尝试如何处理
self.listWidget=self.comboBoxv
?,以及上面提到的一些不一致之处


另一方面,QMainWindow是一个特殊的小部件,因为它已经有一个布局:

因此,您必须在设置布局的位置创建一个centralwidget


如果要使用布局,则不应再使用几何体、移动或调整大小方法,因为布局将处理这些特性


另一方面,我认为您需要创建一个公式,其中有一个描述和一个编辑器,在这种情况下,Qt提供了QFormLayout



您必须了解,编程并不是在放置无意义的代码,例如:您尝试如何处理
self.listWidget=self.comboBoxv
?,以及上面提到的一些不一致之处


另一方面,QMainWindow是一个特殊的小部件,因为它已经有一个布局:

因此,您必须在设置布局的位置创建一个centralwidget


如果要使用布局,则不应再使用几何体、移动或调整大小方法,因为布局将处理这些特性


另一方面,我认为您需要创建一个公式,其中有一个描述和一个编辑器,在这种情况下,Qt提供了QFormLayout



你的问题很清楚,它描述了你遇到的问题,但不清楚你想要什么,因为我能想到很多地方放置CheckableComboBox。你的问题很清楚,它描述了你遇到的问题,但不清楚你想要什么,因为我能想到很多地方放置CheckableComboBoxCheckableComboBox.here,我看到使用中心小部件放置在版面上的所有小部件大小相同,我想知道如何调整每个小部件的大小以进行自定义?在这里,我看到使用中心小部件放置在版面上的所有小部件大小相同,我想知道如何调整每个小部件的大小以进行自定义?
import sys
from PyQt5 import QtCore, QtGui, QtWidgets

class CheckableComboBox(QtWidgets.QComboBox):
    closedPopup = QtCore.pyqtSignal()

    def __init__(self, parent=None):
        super(CheckableComboBox, self).__init__(parent)
        self.setView(QtWidgets.QListView(self))
        self.view().pressed.connect(self.handleItemPressed)
        self.setModel(QtGui.QStandardItemModel(self))

        firstItem = QtGui.QStandardItem("Select Years")
        firstItem.setBackground(QtGui.QBrush(QtGui.QColor(200, 200, 200)))
        firstItem.setSelectable(False)
        self.model().appendRow(firstItem)

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def handleItemPressed(self, index):
        item = self.model().itemFromIndex(index)
        if item.checkState() == QtCore.Qt.Checked:
            item.setCheckState(QtCore.Qt.Unchecked)
        else:
            item.setCheckState(QtCore.Qt.Checked)

    def checkedItems(self):
        l = []
        for i in range(self.model().rowCount()):
            it = self.model().item(i)
            if it.checkState() == QtCore.Qt.Checked:
                l.append(it.text())
        return l

    def hidePopup(self):
        self.closedPopup.emit()
        super(CheckableComboBox, self).hidePopup()
        QtCore.QTimer.singleShot(0, lambda: self.setCurrentIndex(0))

class Dialog_01(QtWidgets.QMainWindow):
    def __init__(self):
        super().__init__()
        self.title = "Title"  
        self.top, self.left, self.width, self.height = 100, 100, 800, 500
        self.initUI()

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

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

    def years(self):
        label = QtWidgets.QLabel('Years')

        years = ["2017", "2018", "2019", "2020", "2021", "2022"]
        self.comboBoxv = CheckableComboBox()
        for i, area in enumerate(years):
            item = QtGui.QStandardItem(area)
            item.setCheckable(True)
            item.setCheckState(QtCore.Qt.Unchecked)
            self.comboBoxv.model().appendRow(item)
        self.flayout.addRow(label, self.comboBoxv)

    @QtCore.pyqtSlot()
    def on_closedPopup(self):
        print(len(self.comboBoxv.checkedItems()))

    def location(self):  
        label = QtWidgets.QLabel('Location')
        combobox = QtWidgets.QComboBox()
        for i in range(1,15):
            combobox.addItem("LOCATION %i" % i)
        self.flayout.addRow(label, combobox)

    def MaxYears(self):
        label = QtWidgets.QLabel('Maximum Years')
        combobox = QtWidgets.QComboBox()
        for i in range(1, 10):
            combobox.addItem(str(i))
        self.flayout.addRow(label, combobox)

if __name__ == '__main__':
    App = QtWidgets.QApplication.instance()
    if App is None:
        App = QtWidgets.QApplication(sys.argv)
    ui = Dialog_01()
    ui.show()
    sys.exit(App.exec_())