PyQt5只向centralWidget添加一个小部件

时间:2018-01-15 16:12:25

标签: python qt pyqt5 sudoku

这是我在stackoverflow上的第一篇文章。到目前为止,stackoverflow对我提高我的python技能非常有帮助。

但是我遇到了这个问题,PyQt只向centralWidget添加了一个小部件,而不是我需要的数独的9x9矩阵。在另一个版本中 - 我使用了两个类来分别创建MainWindow和Widgets。但现在我想只在一个类中实现它。

link1: how it looks

link2: how it should look

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


class mainwindow(QMainWindow, QWidget):
    def __init__(self, parent = None):
        super(mainwindow, self).__init__(parent = parent)
        self.title = 'SUDOKU SOLVER'

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        # add menubar
        menubar = self.menuBar()

        # add drop down items
        exitAct = QAction('&Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit Application')
        exitAct.triggered.connect(qApp.quit)

        newAct = QAction('New', self)
        newAct.setShortcut('Ctrl+N')
        newAct.setStatusTip('New Sudoku')
        newAct.triggered.connect(GameLogic.clearFields)

        rulesAct = QAction('Rules', self)
        rulesAct.setShortcut('Ctrl+R')
        rulesAct.setStatusTip('Sudoku Rules')
        rulesAct.triggered.connect(GameLogic.sudokuRules)

        # add menubar entries
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(newAct)
        fileMenu.addAction(exitAct)

        helpMenu = menubar.addMenu('&Help')
        helpMenu.addAction(rulesAct)

        # call gridlayout function
        l = self.gridLayout()
        self.setCentralWidget(l)

        self.show()

    def gridLayout(self):
        layout = QGridLayout()
        solve = QPushButton('Solve', self)
        solve.clicked.connect(GameLogic.solveSudoku)
        solve.setFixedSize(60, 30)

        mainwindow.fields = {}

        # validate user input
        onlyInt = QIntValidator(1, 9, self)

        # this is the part that doesnt work...
        for x in range(9):
            for y in range(9):
                # keep a reference to the buttons
                mainwindow.fields[(x, y)] = QLineEdit(self)
                mainwindow.fields[(x, y)].setMaxLength(1)
                mainwindow.fields[(x, y)].setValidator(onlyInt)
                mainwindow.fields[(x, y)].setFixedSize(60, 60)
                mainwindow.fields[(x, y)].setFont(QFont('Sans Serif', 20))
                mainwindow.fields[(x, y)].setAlignment(Qt.AlignCenter)
                # add to the layout
                layout.addWidget(mainwindow.fields[(x, y)], x, y)

        layout.addWidget(solve, 10, 4)
        self.setLayout(layout)

class GameLogic():

    def clearFields(self):
        for i in range(9):
            for j in range(9):
                mainwindow.fields[(i, j)].clear()

    def sudokuRules(self):
        pass

    def solveSudoku(self):
        pass

def main():
    app = QApplication(sys.argv)
    ex = mainwindow()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

2 个答案:

答案 0 :(得分:1)

不自行运行,或之前使用过pyQt,

setCentralWidget()需要一个小部件作为参数。 您似乎没有从gridLayout()返回任何内容。

您可能需要创建一个小部件。 使用其布局添加所有内容。 然后通过setCentralWidget()分配此小部件。

P.S。:如果你只是删除l = *,它可能会有效;和setCentralWidget();行,只需致电gridLayout()(可能将其重命名为createGridLayout()

答案 1 :(得分:0)

你有一些基本的错误,但仅此而已。

首先,mainwindow无需继承QMainWindowQWidget,所以

class mainwindow(QMainWindow, QWidget):

...变为

class mainwindow(QMainWindow):

其次,在mainwindow::gridLayout中,您将控件网格放在layout中,然后执行...

self.setLayout(layout)

这几乎肯定会导致警告......

  

QWidget :: setLayout:尝试在主窗口“”上设置QLayout“”,   已经有布局

而是创建一个新的QWidget并将其用作新布局的容器,然后从QWidget返回gridLayout。所以......

self.setLayout(layout)

...变为

w = QWidget()
w.setLayout(layout)
return(w)

完整代码:

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

class mainwindow(QMainWindow):
    def __init__(self, parent = None):
        super(mainwindow, self).__init__(parent = parent)
        self.title = 'SUDOKU SOLVER'

        self.initUI()

    def initUI(self):
        self.setWindowTitle(self.title)
        # add menubar
        menubar = self.menuBar()

        # add drop down items
        exitAct = QAction('&Exit', self)
        exitAct.setShortcut('Ctrl+Q')
        exitAct.setStatusTip('Exit Application')
        exitAct.triggered.connect(qApp.quit)

        newAct = QAction('New', self)
        newAct.setShortcut('Ctrl+N')
        newAct.setStatusTip('New Sudoku')
        newAct.triggered.connect(GameLogic.clearFields)

        rulesAct = QAction('Rules', self)
        rulesAct.setShortcut('Ctrl+R')
        rulesAct.setStatusTip('Sudoku Rules')
        rulesAct.triggered.connect(GameLogic.sudokuRules)

        # add menubar entries
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(newAct)
        fileMenu.addAction(exitAct)

        helpMenu = menubar.addMenu('&Help')
        helpMenu.addAction(rulesAct)

        # call gridlayout function
        l = self.gridLayout()
        self.setCentralWidget(l)

        self.show()

    def gridLayout(self):
        layout = QGridLayout()
        solve = QPushButton('Solve', self)
        solve.clicked.connect(GameLogic.solveSudoku)
        solve.setFixedSize(60, 30)

        mainwindow.fields = {}

        # validate user input
        onlyInt = QIntValidator(1, 9, self)

        # this is the part that doesnt work...
        for x in range(9):
            for y in range(9):
                # keep a reference to the buttons
                mainwindow.fields[(x, y)] = QLineEdit(self)
                mainwindow.fields[(x, y)].setMaxLength(1)
                mainwindow.fields[(x, y)].setValidator(onlyInt)
                mainwindow.fields[(x, y)].setFixedSize(60, 60)
                mainwindow.fields[(x, y)].setFont(QFont('Sans Serif', 20))
                mainwindow.fields[(x, y)].setAlignment(Qt.AlignCenter)
                # add to the layout
                layout.addWidget(mainwindow.fields[(x, y)], x, y)

        layout.addWidget(solve, 10, 4)
        w = QWidget()
        w.setLayout(layout)
        return(w)

class GameLogic():

    def clearFields(self):
        for i in range(9):
            for j in range(9):
                mainwindow.fields[(i, j)].clear()

    def sudokuRules(self):
        pass

    def solveSudoku(self):
        pass

def main():
    app = QApplication(sys.argv)
    ex = mainwindow()

    sys.exit(app.exec_())

if __name__ == '__main__':
    main()