Pavel Pereverzev
Pavel Pereverzev

Reputation: 499

How to set Pyqt widget focus on a new opened item?

I need to make a action similar to what QMessageBox.question() does. Wrote an app that has a simple interface containing buttons, sliders and other stuff. When I change a position of a slider and release mouse button I need a new widget to be appeared and let user choose options only from this new widget. As far as I know QMessageBox.question allows user to select Yes, No or Cancel options.

When question is called like

QMessageBox.question(self, u'Notification', u'Save changes?', QMessageBox.Yes | QMessageBox.No, QMessageBox.No)

the focus that previously were on a main window, goes to question and user has to select something only from question dialog.

I need to open another class with its own buttons but to keep the function that freezes parent app.

Here is a sample

class ResetFilter(QWidget):
    def __init__(self):
        super().__init__()
        self.centerPoint = QDesktopWidget().availableGeometry().center()
        self.width = 320
        self.height = 50
        self.initUI()
    def initUI(self):

        self.setWindowFlags(QtCore.Qt.Window | Qt.WindowStaysOnTopHint)
        self.grid = QGridLayout(self) 
        self.setLayout(self.grid)

        hbox_ques = QHBoxLayout()
        self.grid.addLayout(hbox_ques, 0, 0)

        self.yes = QPushButton(self)
        self.yes.setGeometry(80, 20, 50, 50)
        self.yes.setText(u'YES')

        hbox_ques.addWidget(self.yes)

        self.no = QPushButton(self)
        self.no.setGeometry(140, 20, 50, 50)
        self.no.setText(u'NO')

        hbox_ques.addWidget(self.no)

        self.tmnt = QPushButton(self)
        self.tmnt.setGeometry(200, 20, 50, 50)
        self.tmnt.setText(u'TERMINATE')

        hbox_ques.addWidget(self.tmnt)

        self.setGeometry(self.centerPoint.x() - self.width/2, self.centerPoint.y() - self.height/2, self.width, self.height)

        self.show()


class Pio(QWidget):
    def __init__(self):
        super().__init__()

        self.initUI()

    def initUI(self):
        centerPoint = QDesktopWidget().availableGeometry().center()
        self.setWindowFlags(QtCore.Qt.Window | Qt.WindowStaysOnTopHint)
        self.launch = False

        self.grid = QGridLayout(self) 
        self.setLayout(self.grid)

        hbox_lbl = QHBoxLayout()

        self.grid.addLayout(hbox_lbl, 0, 0)
        self.slider = QSlider(Qt.Horizontal)
        self.slider.sliderReleased.connect(self.ids_change)


        hbox_lbl.addWidget(self.slider)

        self.move(centerPoint.x() - self.width()/2, centerPoint.y() - self.height()/2)
        self.show()

    def ids_change(self):
        self.item_reset = ResetFilter()
        self.item_reset.show()
        self.item_reset.setFocusPolicy(Qt.StrongFocus)

mainWin = Pio()       
mainWin.show()

Upvotes: 1

Views: 922

Answers (1)

Heike
Heike

Reputation: 24430

If I understand your question correctly you want to freeze the main window while the popup window is open. To achieve this you could make ResetFilter a subclass of QDialog and make it modal e.g.

class ResetFilter(QDialog):
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.setModal(True)
        # rest as before

In Pio.ids_change you would then need to initiate ResetFilter with self as its parents, e.g.

    def ids_change(self):
        self.item_reset = ResetFilter(self)

Upvotes: 1

Related Questions