1

I have a few questions.

  1. How do i properly get settings from the child window when i press 'Print' button?

  2. How do i close the Settings window and save/commit changes only when user presses 'OK' vs 'Cancel' which just closes the dialog and dismisses the changes.

enter image description here

Settings Window

import sys
from PySide import QtGui, QtCore


class SettingsWindow(QtGui.QDialog):
    def __init__(self, parent=None):
        super(SettingsWindow, self).__init__(parent)
        self.resize(200, 150)
        self.setWindowTitle('Settings')
        self.initUI()

    def initUI(self):

        lb_max = QtGui.QLabel('Max')
        self.ui_max = QtGui.QSpinBox()
        self.ui_max.setValue(5)

        lb_min = QtGui.QLabel('Min')
        self.ui_min = QtGui.QSpinBox()
        self.ui_min.setValue(10)

        lb_count = QtGui.QLabel('Count')
        self.ui_count = QtGui.QSpinBox()
        self.ui_count.setValue(25)

        self.buttons = QtGui.QDialogButtonBox();
        self.buttons.setOrientation(QtCore.Qt.Horizontal)
        self.buttons.setStandardButtons(QtGui.QDialogButtonBox.Ok|QtGui.QDialogButtonBox.Cancel)
        self.buttons.layout().setDirection(QtGui.QBoxLayout.LeftToRight)

        grid = QtGui.QGridLayout()
        grid.setContentsMargins(10,10,10,10)
        grid.addWidget(lb_max,0,0)
        grid.addWidget(self.ui_max,0,1)
        grid.addWidget(lb_min,1,0)
        grid.addWidget(self.ui_min,1,1)
        grid.addWidget(lb_count,2,0)
        grid.addWidget(self.ui_count,2,1)
        grid.addWidget(self.buttons,3,1)

        self.setLayout(grid)

Main Window

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(MainWindow, self).__init__(parent)
        self.resize(200, 150)
        self.setWindowTitle('Assets')
        self.initUI()

    def initUI(self):

        self.mi_settings = QtGui.QAction('Settings', self)
        self.mi_settings.triggered.connect(self.open_settings)

        self.ui_button = QtGui.QPushButton('Print')
        self.ui_button.clicked.connect(self.clicked_button)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(self.mi_settings)

        grid = QtGui.QVBoxLayout()
        grid.setContentsMargins(10,10,10,10)
        grid.addWidget(self.ui_button)

        main_widget = QtGui.QWidget()
        main_widget.setLayout(grid)
        self.setCentralWidget(main_widget)

    def open_settings(self):
        win = SettingsWindow()
        win.exec_()

    def clicked_button(self):
        print 'Settings'
        print '\tMax: '
        print '\tMin: '
        print '\tCount: '


if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = MainWindow()
    # ex = SettingsWindow()
    ex.show()
    sys.exit(app.exec_())
JokerMartini
  • 5,674
  • 9
  • 83
  • 193

2 Answers2

1

Firstly, you need to connect up the buttons in the dialog, so that you can tell whether the user cancelled it or not:

class SettingsWindow(QtGui.QDialog):
    ...
    def initUI(self):
        ...
        self.buttons = QtGui.QDialogButtonBox()
        ...
        self.buttons.accepted.connect(self.accept)
        self.buttons.rejected.connect(self.reject)

Secondly, you should think about how you set the defaults in the dialog, and how you reset/retrieve the current values. One way to do this would be to have a central settings dictionary where you store the values, with the dialog being used to update it from user input:

class SettingsWindow(QtGui.QDialog):
    ...
    def getValues(self):
        return {
            'max': self.ui_max.value(),
            'min': self.ui_min.value(),
            'count': self.ui_count.value(),
            }

    def setValues(self, settings):
        self.ui_max.setValue(settings['max'])
        self.ui_min.setValue(settings['min'])
        self.ui_count.setValue(settings['count'])

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent=None):
        ...
        # default values
        self.settings = {
            'max': 5,
            'min': 10,
            'count': 25,
            }

    def open_settings(self):
        win = SettingsWindow()
        # reset from current values
        win.setValues(self.settings)
        if win.exec_() == QtGui.QDialog.Accepted:
            # update only if user clicked ok
            self.settings.update(win.getValues())

    def clicked_button(self):
        print 'Settings:'
        for key in 'max', 'min', 'count':
            print '\t%s = %s' % (key.title(), self.settings[key])

There are numerous ways to solve this kind of problem, but this should give you the general idea.

ekhumoro
  • 115,249
  • 20
  • 229
  • 336
0

You can check the result of the exec_() command to see whether the dialog was accepted or rejected. If it was accepted, you can read the values of the GUI controls

win = SettingsWindow()
r = win.exec_()
if r:
    min_val = win.ui_min.value()
    max_val = win.ui_max.value()
    cnt_val = win.ui_max.value()
Brendan Abel
  • 35,343
  • 14
  • 88
  • 118
  • what about when a user hits cancel for ok. when i open the dialog and the settings being what the user last chose – JokerMartini Feb 07 '17 at 18:28
  • Currently, the settings window values will reset each time you open the window. If you want them to represent the *current* settings, you need to modify the settings window to accept arguments so you can pass in the *current* settings -- `SettingsWindow(self, settings={'min': 4, 'max': 10, 'count': 50})` and then use those settings to set the values of the GUI elements – Brendan Abel Feb 07 '17 at 18:31