Форум сайта python.su
Patrik, точно по центру исходя из моего предыдущего примера будет так:
# -*- coding: utf-8 -*- from PyQt4 import QtCore, QtGui class ModalWind(QtGui.QWidget): def __init__(self, parent=None): super(ModalWind, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint) self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle("Модальное окно") butt_hide = QtGui.QPushButton('Закрыть модальное окно') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_hide) self.setLayout(vbox) butt_hide.clicked.connect(self.close) class MainWind(QtGui.QWidget): def __init__(self, parent=None): super(MainWind, self).__init__(parent) self.setWindowTitle("Главное окно") self.resize(400, 200) butt_show = QtGui.QPushButton('Показать модальное окно') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_show) self.setLayout(vbox) butt_show.clicked.connect(self.on_show) def on_show(self): win = ModalWind(self) win.resize(200, 100) # сначало отображаем окно за пределами видимости win.move(win.width()*-2,0) # обязательно отображаем, потому-что, только так frameSize() # вернет коректное значение win.show() x = self.x()+(self.frameSize().width()-win.frameSize().width())//2 y = self.y()+(self.frameSize().height()-win.frameSize().height())//2 win.move(x, y) if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) window = MainWind() window.show() sys.exit(app.exec_())
Отредактировано Loki (Март 29, 2013 13:52:38)
Офлайн
Loki А если нужно несколько модальных окно, то просто вводим новый классы class ModalWind1, 2 т.п?
Офлайн
Все зависит от твоей задачи…
К примеру, если бы у тебя стояла задача запускать модальные окна из одного основного, и чтобы все модальные окна запускались обязательно по центру родителя, то разумно было бы ввести в основной класс новый метод, которому бы передавались ссылки на сами модальные окна, и уже в этом методе двигать их…
P.S. Просто совет… старайся своим классам давать емкие, но достаточно развернутые имена, исходя из их функционала… Modal1, Modal2 такие названия лучше использовать только в примерах, а не в своих программах…
Офлайн
У меня в программе всего будет три модальных окна:
1) о программе
2) окошко информация
3) окошко с ошибкой
Все будут вылетать по центру.
Имена классам я стараюсь давать названия, чтобы соответсвовали назначению.
Еще попутный вопрос появился, к примеру в окне с ошибкой, перед текстом хочу вставить картинку восклицательный знак.
Я правильно понимаю, что нужно поставить label и в качестве фона задать ему картинку?
Офлайн
Мне кажется лучше воспользоваться QtGui.QMessageBox.warning(<родитель>,<Текст сообщения>), метод возвращает код нажатой кнопки, если укажешь родителя будет центроваться относительно его и будет его модалить(насколько я помню)…
Не понравится этот виджет посмотри QMessageBox.
Офлайн
Я думал взять виджет QWidget в нем вывести картинку label.setPixmap(pixmap) и label с описанием ошибки и кнопку закрыть. Единственное, что я не понимаю. К примеру класс назову
class Error(QtGui.QWidget), если модифицировать твой пример:
# -*- coding: utf-8 -*- from PyQt4 import QtCore, QtGui class Error(QtGui.QWidget): def __init__(self, parent=None): super(Error, self).__init__(parent) ... class ModalWind(QtGui.QWidget): def __init__(self, parent=None): super(ModalWind, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint) self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle("Модальное окно") butt_hide = QtGui.QPushButton('Закрыть модальное окно') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_hide) self.setLayout(vbox) butt_hide.clicked.connect(self.close) class MainWind(QtGui.QWidget): def __init__(self, parent=None): super(MainWind, self).__init__(parent) self.setWindowTitle("Главное окно") self.resize(400, 200) butt_show = QtGui.QPushButton('Показать модальное окно') butt_error = QtGui.QPushButton('Показать окно об ошибке') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_show) vbox.addWidget(butt_error) self.setLayout(vbox) butt_show.clicked.connect(self.on_show) butt_error.clicked.connect(self.on_show) def on_show(self): win = ModalWind(self) win.resize(200, 100) # сначало отображаем окно за пределами видимости win.move(win.width()*-2,0) # обязательно отображаем, потому-что, только так frameSize() # вернет коректное значение win.show() x = self.x()+(self.frameSize().width()-win.frameSize().width())//2 y = self.y()+(self.frameSize().height()-win.frameSize().height())//2 win.move(x, y) if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) window = MainWind() window.show() sys.exit(app.exec_())
Офлайн
Patrik, я практически ничего не понял, что ты хочешь сделать…
Обьясни по подробнее, что ты хочешь сделать, и как это должно работать.
Из того что ты написал я понял, что тебе лучше использовать МэсэджБоксы для вывода сообщения об ошибке…
По поводу передать класс методу…Твой класс находится в глобальной области видимости имен, ты его можешь вызвать непосредственно внутри метода другого класса…или я что-то не так понял.
Офлайн
Если ты хотел на нажатие другой кнопки повесить окно Ошибки, то:
# -*- coding: utf-8 -*- from PyQt4 import QtCore, QtGui class Error(QtGui.QWidget): def __init__(self, parent=None): super(Error, self).__init__(parent) ... class ModalWind(QtGui.QWidget): def __init__(self, parent=None): super(ModalWind, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint) self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle("Модальное окно") butt_hide = QtGui.QPushButton('Закрыть модальное окно') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_hide) self.setLayout(vbox) butt_hide.clicked.connect(self.close) class MainWind(QtGui.QWidget): def __init__(self, parent=None): super(MainWind, self).__init__(parent) self.setWindowTitle("Главное окно") self.resize(400, 200) butt_show = QtGui.QPushButton('Показать модальное окно') butt_error = QtGui.QPushButton('Показать окно об ошибке') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_show) vbox.addWidget(butt_error) self.setLayout(vbox) butt_show.clicked.connect(self.on_show) butt_error.clicked.connect(self.on_show_error) def on_show(self): win = ModalWind(self) win.resize(200, 100) # сначало отображаем окно за пределами видимости win.move(win.width()*-2,0) # обязательно отображаем, потому-что, только так frameSize() # вернет коректное значение win.show() x = self.x()+(self.frameSize().width()-win.frameSize().width())//2 y = self.y()+(self.frameSize().height()-win.frameSize().height())//2 win.move(x, y) def on_show_error(self): win_er = Error(self) ... win_er.show() x = self.x()+(self.frameSize().width()-win_er.frameSize().width())//2 y = self.y()+(self.frameSize().height()-win_er.frameSize().height())//2 win_er.move(x, y) if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) window = MainWind() window.show() sys.exit(app.exec_())
Офлайн
А есть возможность объединить 2 метода on_show и on_show_error они же дублируют друг дргуга?
Офлайн
Patrik, Есть и такой, но мне этот способ кажется не очень предпочтительным.
Я еще раз повторяю зачем изобретать велосипед, если в Qt уже есть QMessageBox?
Но если ты не ишешь легких путей, то:
# -*- coding: utf-8 -*- from PyQt4 import QtCore, QtGui # я немного дописал твой класс, чтобы проще было проверить работоспособность class Error(QtGui.QWidget): def __init__(self, parent=None): super(Error, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint) self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle('Окно с ошибкой') butt_hide = QtGui.QPushButton('Закрыть окно c ошибкой') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_hide) self.setLayout(vbox) butt_hide.clicked.connect(self.close) class ModalWind(QtGui.QWidget): def __init__(self, parent=None): super(ModalWind, self).__init__(parent) self.setWindowFlags(QtCore.Qt.Dialog | QtCore.Qt.WindowSystemMenuHint) self.setWindowModality(QtCore.Qt.WindowModal) self.setWindowTitle("Модальное окно") butt_hide = QtGui.QPushButton('Закрыть модальное окно') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_hide) self.setLayout(vbox) butt_hide.clicked.connect(self.close) class MainWind(QtGui.QWidget): def __init__(self, parent=None): super(MainWind, self).__init__(parent) self.setWindowTitle("Главное окно") self.resize(400, 200) butt_show = QtGui.QPushButton('Показать модальное окно') butt_error = QtGui.QPushButton('Показать окно об ошибке') vbox = QtGui.QVBoxLayout() vbox.addWidget(butt_show) vbox.addWidget(butt_error) self.setLayout(vbox) # здесь на сигнал вместо ссылки вешаешь лямбду с параметром butt_show.clicked.connect(lambda: self.on_show(ModalWind)) butt_error.clicked.connect(lambda: self.on_show(Error)) def on_show(self, widget): win = widget(self) win.resize(200, 100) # сначало отображаем окно за пределами видимости win.move(win.width()*-2,0) # обязательно отображаем, потому-что, только так frameSize() # вернет коректное значение win.show() x = self.x()+(self.frameSize().width()-win.frameSize().width())//2 y = self.y()+(self.frameSize().height()-win.frameSize().height())//2 win.move(x, y) if __name__ == "__main__": import sys app = QtGui.QApplication(sys.argv) window = MainWind() window.show() sys.exit(app.exec_())
Офлайн