How to center QMessageBox and QInputDialog on the screen?

假如想象 提交于 2020-01-30 06:50:21

问题


I have this function to center an object in the middle of the screen.

I want to center a QMainWindow, QInputDialog and a QMessageBox.

This is my MessageBox:

def _Warning(self,_type):
        infoBox = QtWidgets.QMessageBox()
        infoBox.setIcon(QtWidgets.QMessageBox.Warning)
        infoBox.setWindowTitle("Warning")
        if (_type=="File"):
            infoBox.setText("The File Already exist in the current Directory")
        else:
            infoBox.setText("The Folder Already exist in the current Directory")

        self.center(infoBox)

        infoBox.exec_()

This is my QInputDialog:

def AddFile_B(self):
        self.cuadro = QInputDialog()
        self.center(self.cuadro)
        text, okPressed = self.cuadro.getText(self, "New File","File Name:", QLineEdit.Normal, "")
        if okPressed and text != '':
            file = File_Node(text)
            verify = self.bonsai_B.addChild(file)
            if (verify == True):
                item = QtWidgets.QListWidgetItem(None,0)
                self.TreeB.addItem(item)
            else:
                del file
                self._Warning("File")

This is My Center Function:

def center(self,object):
    qtRectangle = object.frameGeometry() 
    centerPoint = QtWidgets.QDesktopWidget().availableGeometry().center()
    qtRectangle.moveCenter(centerPoint)
    object.move(qtRectangle.topLeft())

I can only center the QMainWindow.

The logic is to move the object into the topLeft Point (screenWidth/2 - objectWidth/2, screenHeight/2 - objectHeight/2) but I don't know what I am doing wrong.


回答1:


- QMessageBox

In the case of QMessageBox this is resized in the exec_() method, so a possible solution is to use QTimer.singleShot() to change the geometry a moment after being displayed.

from functools import partial
from PyQt5 import QtCore, QtWidgets


def center(window):
    # https://wiki.qt.io/How_to_Center_a_Window_on_the_Screen

    window.setGeometry(
        QtWidgets.QStyle.alignedRect(
            QtCore.Qt.LeftToRight,
            QtCore.Qt.AlignCenter,
            window.size(),
            QtWidgets.qApp.desktop().availableGeometry(),
        )
    )


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.btn_warning = QtWidgets.QPushButton(
            "Open QMessageBox", clicked=self.open_qmessagebox
        )

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.btn_warning)

        center(self)

    @QtCore.pyqtSlot()
    def open_qmessagebox(self):
        infoBox = QtWidgets.QMessageBox()
        infoBox.setIcon(QtWidgets.QMessageBox.Warning)
        infoBox.setWindowTitle("Warning")
        infoBox.setText("The XXX Already exist in the current Directory")
        wrapper = partial(center, infoBox)
        QtCore.QTimer.singleShot(0, wrapper)
        infoBox.exec_()


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())

- QInputDialog

In the case of QInputDialog, the QInputDialog::getText() method is static, so the "self.cuadro" object is not the window since the window is created within that method. If you pass a parent to getText() then by default it will be centered with respect to that.

So if the QMainWindow is centered and assuming that QMainWindow is the self then it is not necessary to modify anything.

If instead the parent is not centered on the screen then there are 2 possible solutions:

  • Do not use the static method and implement the logic through a QInputDialog instance:
from functools import partial
from PyQt5 import QtCore, QtWidgets


def center(window):
    # https://wiki.qt.io/How_to_Center_a_Window_on_the_Screen

    window.setGeometry(
        QtWidgets.QStyle.alignedRect(
            QtCore.Qt.LeftToRight,
            QtCore.Qt.AlignCenter,
            window.size(),
            QtWidgets.qApp.desktop().availableGeometry(),
        )
    )


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.btn_inputdialog = QtWidgets.QPushButton(
            "Open QInputDialog", clicked=self.open_qinputdialog
        )

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.btn_inputdialog)

        center(self)

    @QtCore.pyqtSlot()
    def open_qinputdialog(self):
        dialog = QtWidgets.QInputDialog(self)
        dialog.setWindowTitle("New File")
        dialog.setLabelText("File Name:")
        dialog.setTextEchoMode(QtWidgets.QLineEdit.Normal)
        dialog.setTextValue("")
        wrapper = partial(center, dialog)
        QtCore.QTimer.singleShot(0, wrapper)
        text, okPressed = (
            dialog.textValue(),
            dialog.exec_() == QtWidgets.QDialog.Accepted,
        )
        if okPressed and text:
            print(text)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())
  • Continue using the static method and get the window using findChildren()
from functools import partial
from PyQt5 import QtCore, QtWidgets


def center(window):
    # https://wiki.qt.io/How_to_Center_a_Window_on_the_Screen

    window.setGeometry(
        QtWidgets.QStyle.alignedRect(
            QtCore.Qt.LeftToRight,
            QtCore.Qt.AlignCenter,
            window.size(),
            QtWidgets.qApp.desktop().availableGeometry(),
        )
    )


class Widget(QtWidgets.QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)

        self.btn_inputdialog = QtWidgets.QPushButton(
            "Open QInputDialog", clicked=self.open_qinputdialog
        )

        lay = QtWidgets.QVBoxLayout(self)
        lay.addWidget(self.btn_inputdialog)

        center(self)

    @QtCore.pyqtSlot()
    def open_qinputdialog(self):
        parent = self
        dialogs = parent.findChildren(QtWidgets.QInputDialog)

        def onTimeout():
            dialog, *_ = set(parent.findChildren(QtWidgets.QInputDialog)) - set(dialogs)
            center(dialog)

        QtCore.QTimer.singleShot(0, onTimeout)
        text, okPressed = QtWidgets.QInputDialog.getText(
            parent, "New File", "File Name:", QtWidgets.QLineEdit.Normal, ""
        )
        if okPressed and text:
            print(text)


if __name__ == "__main__":
    import sys

    app = QtWidgets.QApplication(sys.argv)
    w = Widget()
    w.show()
    sys.exit(app.exec_())


来源:https://stackoverflow.com/questions/57742263/how-to-center-qmessagebox-and-qinputdialog-on-the-screen

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!