Hello Vojtech

Impressive what you are able to do!!! I can't find my bugs with good eyes and have no idea how one would find them without seeing the code. I changed a few things in your file and hope, the resulting solution fits your needs:

- fixed rowCount of your sudoku (was 10, now 9)
- overwrote QPushButton and QSpinBox to store their index and to implement custom keyPressEvent behaviour
- navigate using arrows, start editing by hitting enter or return.
- change value of the spinbox using arrows, finish editing by hitting enter, continue navigating

I hope this helps! If you have further questions, feel free to ask again!

Merry Christmas! Aaron





Am 22.12.2013 18:15, schrieb Vojtěch Polášek:
Greetings,
my name is Vojtěch Polášek and I am a blind student from czech Republic.
I am creating an application in Pyside with Python 3.2. I would like to
create a sudoku game accessible for blind and visually impaired people.
I have created a main window, added a widget which contains 81 buttons
in a grid layout. Now my idea is, that after pressing a button, that
button would disappear and would be replaced by some other controll
which would allow you to change the value. I chose QSpinBox for now.
This step works well, although I had to implement my own eventfilter,
because QT in Linux uses arrows to browse available elements on the
screen. Never mind.
Now this is the way in which I replace a button with a spinbox. This
function is connected to the QPushButton.clicked signal:
     def editValue(self):
         print ('editing')
         senderpos =
self.grid.getItemPosition(self.grid.indexOf(self.sender()))
         self.grid.addWidget(self.spinbox, senderpos[0], senderpos[1])
         print ('added')
         self.spinbox.setValue(int(self.sender().text()))
         print ('value set')
         self.spinbox.show()
         print('showed')
         self.spinbox.setFocus()
         print('focused')
         self.spinbox.editingFinished.connect(self.storeValue)
         print('connected')

Don't mind those print statements, they are there for debugging
purposes, because I haven't found a way of debugging Pyside with PDB.
The problem is, that this signal is also called after I press a button
and this function is executed. I don't manipulate with spinbox in any
manner. Only thing that is set is its accepted range of input.
What could be the problem?
I am attaching the source code.
Thank you very much,
Vojtěch Polášek


_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside

#!/usr/bin/env python

import sys, time
from PySide import QtGui, QtCore

class MainWindow(QtGui.QMainWindow):
    def __init__(self):
        super (MainWindow, self).__init__()
        self.setCentralWidget(SudokuBoard(self))
        self.setWindowTitle ("test")
        self.show()

class Button(QtGui.QPushButton):

    def __init__(self, text, index, parent):
        super (Button, self).__init__(text, parent)
        self.index = index

    def keyPressEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Up, QtCore.Qt.Key_Down, QtCore.Qt.Key_Left, QtCore.Qt.Key_Right, QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            event.ignore()

class SpinBox(QtGui.QSpinBox):

    def __init__(self, value, index, parent):
        super (SpinBox, self).__init__(parent)
        self.setRange (1, 9)
        self.setValue(value)
        self.index = index

    def keyPressEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return]:
            self.editingFinished.emit()
        else:
            super (SpinBox, self).keyPressEvent(event)



class SudokuBoard(QtGui.QWidget):
    def __init__(self, parent):
        super (SudokuBoard, self).__init__(parent)
        self.initUI()

    def initUI(self):
        self.grid = QtGui.QGridLayout()
        self.buttons = {}
        for i in range(0, 81):
            button = Button(str(i+1), i, self)
            self.buttons[i] = button
            self.grid.addWidget(button, i / 9, i % 9)
            self.buttons[i].clicked.connect(self.editValue)
            button.setStyleSheet("QPushButton:focus{ background-color: green; }")

        self.setLayout (self.grid)
#
        self.setGeometry (500, 500, 500, 600)

    def keyPressEvent(self, event):
        if event.key() in [QtCore.Qt.Key_Up, QtCore.Qt.Key_Down, QtCore.Qt.Key_Left, QtCore.Qt.Key_Right]:

            offsets = {QtCore.Qt.Key_Up: -9,
                       QtCore.Qt.Key_Down: 9,
                       QtCore.Qt.Key_Left: -1,
                       QtCore.Qt.Key_Right: 1}

            new_index = self.focusWidget().index + offsets[event.key()]

            if (new_index >= 0) and (new_index <= 80):
                self.buttons[new_index].setFocus()

        elif event.key() in [QtCore.Qt.Key_Enter, QtCore.Qt.Key_Return] and isinstance(self.focusWidget(), QtGui.QPushButton):
            self.editValue()

    def editValue(self):
        print 'editing'
        button = self.focusWidget()
        index = button.index

        self.grid.removeItem(self.grid.itemAtPosition(index / 9, index % 9))
        button.hide()

        spinbox = SpinBox(int(button.text()), index, self)
        spinbox.setFocus()
        spinbox.editingFinished.connect(self.storeValue)
        self.grid.addWidget(spinbox, index / 9, index % 9)

    def storeValue(self):
        print 'storing'
        spinbox = self.sender()
        spinbox.editingFinished.disconnect(self.storeValue) # otherwise storeValue is called twice, once when enter is pressed, once when losing focus
        index = spinbox.index
        button = self.buttons[index]
        button.show()
        button.setFocus()
        self.grid.removeItem(self.grid.itemAtPosition(index / 9, index % 9))
        spinbox.hide()
        self.grid.addWidget(button, index / 9, index % 9)


def main():
    app = QtGui.QApplication(sys.argv)
    w = MainWindow()
    sys.exit (app.exec_())

main()
_______________________________________________
PySide mailing list
[email protected]
http://lists.qt-project.org/mailman/listinfo/pyside

Reply via email to