PyQt5 从 main 开始第二个 window
PyQt5 opening second window from main
嗨,我是 python 的新手(直到第 3 讲和麻省理工学院 6001 计算机科学与编程导论
在 Python) 尽管我开始玩 PyQt5 和 Designer (Python3, PyQt5, on linux).
我阅读了一点 PyQt5,但对面向对象编程和 Qt 了解不多
文档就像我一样的克林贡语。无法弄清楚为什么这个脚本 test.py 无法打开第二个
window,其实是打开的,在第一个window
前面desolve之前我可以简单看到
当我按下退出按钮时?有什么帮助吗?以及在哪里可以找到
逻辑的任何一种简单资源
Qt 的不同 类 和像我这样没有受过教育的应用程序循环。
test.py
!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
@author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QDesktopWidget
def main():
class quitto(QtWidgets.QMainWindow):
def __init__(self):
super(quitto, self).__init__()
uic.loadUi('exitmain.ui', self)
self.center()
self.show()
print('inside quitting2 ' *5)
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class menu(QtWidgets.QMainWindow):
def __init__(self):
super(menu, self).__init__()
uic.loadUi('main.ui', self)
self.ButtonQ.clicked.connect(self.QPushButtonQPressed)
self.center()
self.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def QPushButtonQPressed(self):
#This is executed when the button is pressed
print('buttonB pressed' *5)
pippo=quitto()
pippo.show()
app = QtWidgets.QApplication(sys.argv)
window=menu()
app.exec_()
if __name__ == '__main__':
和main.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="resource001.qrc">
<normaloff>:/main/python.png</normaloff>
<normalon>:/main/python.png</normalon>
<disabledoff>:/main/python.png</disabledoff>
<disabledon>:/main/python.png</disabledon>
<activeoff>:/main/python.png</activeoff>
<activeon>:/main/python.png</activeon>
<selectedoff>:/main/python.png</selectedoff>
<selectedon>:/main/python.png</selectedon>:/main/python.png</iconset>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #9de650;
}
QPushButton:hover{
background-color: green;
}
QPushButton#ButtonQ{
background-color: orange;
}
QPushButton#ButtonQ:hover{
background-color: red;
}</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>0</y>
<width>471</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
<underline>true</underline>
</font>
</property>
<property name="text">
<string>House-Buying-Menu</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="ButtonA">
<property name="geometry">
<rect>
<x>170</x>
<y>100</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>A</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonB">
<property name="geometry">
<rect>
<x>170</x>
<y>210</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>B</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonC">
<property name="geometry">
<rect>
<x>170</x>
<y>320</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonQ">
<property name="geometry">
<rect>
<x>170</x>
<y>450</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>QUIT</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources>
<include location="resource001.qrc"/>
</resources>
<connections/>
</ui>
和mainexit.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>631</width>
<height>496</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>200</x>
<y>310</y>
<width>174</width>
<height>33</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>631</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
该行为的原因是您正在创建的 quitto
实例是 "garbage collected"。像许多高级语言一样,Python 有一个自动管理内存的系统,并负责释放它 "decides" 不再有用的对象的内存。
在函数内创建的任何局部变量总是在函数 returns 后立即删除,除非它以某种方式引用到持久对象。
下面的例子用更简单的方式解释了它:"my_variable"是在function
中创建的,但是一旦它完成(它returns)python就会删除那个变量,这很好,因为如果不这样做,你很容易就会内存不足:
class DeletingObject(object):
'''
A basic class that prints a message whenever any of its instances
is going to be deleted.
'''
def __del__(self):
print('Goodbye cruel world...')
def function():
my_variable = DeletingObject()
print(my_variable)
>>> function()
<__main__.DeletingObject object at 0xb593a46c>
Goodbye cruel world...
同样的事情发生在你的情况下:你创建了 quitto
,但是没有它的永久引用,所以一旦创建它的函数 returns,它就被删除了。
当您在 class 中创建对象时,避免这种情况的最常见方法是使新对象成为 实例属性 :
def QPushButtonQPressed(self):
<b>self.pippo</b> = quitto()
self.pippo.show()
现在新对象不再被删除,window也不会再被销毁
由于您刚刚开始研究所有这些,我想分享一些关于您的示例的建议:
- classes 不应在函数内声明;在某些情况下可以这样做,但它们是非常特殊的情况,通常不需要通用用法(主要原因是 classes 应该可以从任何地方访问,以便可以随时创建它们的实例,但也是因为在函数中定义一个class意味着每次函数都是运行时总是声明它,这对性能来说不是很好);
- 仅在分隔代码的逻辑片段时才在函数中使用空行,而不是在每一行之间;
- 大多数语言的共同约定是对 classes 使用大写名称,对函数、变量和实例使用小写名称,请阅读官方 style guide for Python(a.k.a.PEP-8);
- 虽然从技术上讲它没有任何问题,但通常最好不要混合从模块导入的方式,尤其是当有多个级别的子模块时(例如 PyQt):您要么像在第一行 (
from PyQt5 import QtWidgets
) 或您将要使用的单个 classes,就像您在第二次导入时所做的那样 (from PyQt5.QtWidgets import QDesktopWidget
);第二种方法通常适用于简单的情况,但如果您的代码增长很多,您可能会发现自己有数十个 class 必须手动导入,虽然您可以 from PyQt5.QtWidgets import *
通常更好导入子模块并从那里访问 classes:
from PyQt5 import QtWidgets
# ...
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
- QDesktopWidget 已过时,请改用 QScreen;
@musicamante 感谢您详尽详尽的 post(我投了赞成票,但不算数,对不起)不确定我是否必须再 post 关于下一个问题,但它是相关的到上面的那个。我一直在努力让我的脚本正常工作,结果是:
test2.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
@author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic
#import resource
def main():
class Quitto(QtWidgets.QDialog):
def quitbuttonboxquit(self):
print('system exit')
app.quit()
def quitbuttonboxnonquit(self):
print('return to main')
window.show()
self.close()
def __init__(self):
super(Quitto, self).__init__()
uic.loadUi('exitdialog2.ui', self)
self.center()
self.show()
print('inside quitting2 ' *5)
self.QuitbuttonBox.accepted.connect(self.quitbuttonboxquit)
self.QuitbuttonBox.rejected.connect(self.quitbuttonboxnonquit)
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def closeEvent(self, event):
event.ignore()
class Menu(QtWidgets.QMainWindow):
def __init__(self):
super(Menu, self).__init__()
uic.loadUi('main.ui', self)
self.ButtonQ.clicked.connect(self.qpushbuttonqpressed)
self.center()
self.show()
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def qpushbuttonqpressed(self): #This is executed when the button is pressed
print('buttonB pressed' *5)
window.hide()
pippo=Quitto()
pippo.exec_()
def closeEvent(self, event): #Your desired functionality here
event.ignore()
app = QtWidgets.QApplication(sys.argv)
sshFile="coffee.qss"
with open(sshFile,"r") as fh:
app.setStyleSheet(fh.read())
window=Menu()
app.exec_()
if __name__ == '__main__':
main()
和exitdialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>586</width>
<height>522</height>
</rect>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QDialogButtonBox" name="QuitbuttonBox">
<property name="geometry">
<rect>
<x>40</x>
<y>460</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #17eb3e;
}
QPushButton:hover{
background-color: red;
}
</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>30</y>
<width>491</width>
<height>341</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/main/alert.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>170</x>
<y>400</y>
<width>271</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel {
color : red
}</string>
</property>
<property name="text">
<string>Are you sure to Quit ?!?</string>
</property>
</widget>
</widget>
<resources>
<include location="resource001.qrc"/>
</resources>
<connections>
<connection>
<sender>QuitbuttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>QuitbuttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
稍后我将尝试拆分函数和 classes(首先我需要弄清楚 classes)
尽管如此,我还是将 class Quitto 更改为 :
class Quitto(QtWidgets.QDialog)
并更改:
def qpushbuttonqpressed(self): #This is executed when the button is pressed
print('buttonB pressed' *5)
window.hide()
pippo=Quitto()
pippo.exec_()
在之前的脚本中使用:
-- window.hide() 在短暂显示两个 windows
后关闭了所有内容
同时使用
-- pippo.exec() 而不是 pippo.show() 在
之上显示了新的第二个 window
其他,关闭它们后我得到了:
AttributeError: 'quitto' object has no attribute 'exec_'
在第二个脚本中使用 pippo.show() 也没有用,但是 pippo.exe_() 做了
技巧。它如何绕过垃圾收集???
以及为什么将 class Quitto() 更改为 QtWidgets.QMainWindow 我收到属性错误?
在我的项目中,我使用它从主 window 打开另一个 window。我粘贴了具有额外中心功能的全功能脚本,将 main windows 放在屏幕中间。从 Designer 创建两个文件,“UIMain.ui”(主 windows)和第二个 window“notes.ui”并保存它们。
# Open Second Window/Dialog/Form from Main Window
from PyQt5 import uic
from PyQt5.QtWidgets import (
QMainWindow,
QApplication,
QDesktopWidget
)
form_2, base_2 = uic.loadUiType('notes.ui')
class MainNotes(base_2, form_2):
def __init__(self, parent=None):
super(base_2, self).__init__(parent)
self.setupUi(self)
class MainApp(QMainWindow):
""" Main Class
"""
def __init__(self):
super(MainApp, self).__init__()
self.mainnotes = MainNotes()
self.ui = uic.loadUi('UIMain.ui', self)
self.initapp()
def initapp(self):
self.ui.bt_notes.clicked.connect(self.notes)
def notes(self):
"""
Put your code here
"""
self.mainnotes.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
import sys
try:
myapp = QApplication([])
mywindow = MainApp()
mywindow.center()
mywindow.show()
myapp.exec_()
except SystemExit:
sys.exit(0)
if __name__ == '__main__':
main()
嗨,我是 python 的新手(直到第 3 讲和麻省理工学院 6001 计算机科学与编程导论
在 Python) 尽管我开始玩 PyQt5 和 Designer (Python3, PyQt5, on linux).
我阅读了一点 PyQt5,但对面向对象编程和 Qt 了解不多
文档就像我一样的克林贡语。无法弄清楚为什么这个脚本 test.py 无法打开第二个
window,其实是打开的,在第一个window
前面desolve之前我可以简单看到当我按下退出按钮时?有什么帮助吗?以及在哪里可以找到
逻辑的任何一种简单资源Qt 的不同 类 和像我这样没有受过教育的应用程序循环。
test.py
!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
@author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic
from PyQt5.QtWidgets import QDesktopWidget
def main():
class quitto(QtWidgets.QMainWindow):
def __init__(self):
super(quitto, self).__init__()
uic.loadUi('exitmain.ui', self)
self.center()
self.show()
print('inside quitting2 ' *5)
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
class menu(QtWidgets.QMainWindow):
def __init__(self):
super(menu, self).__init__()
uic.loadUi('main.ui', self)
self.ButtonQ.clicked.connect(self.QPushButtonQPressed)
self.center()
self.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def QPushButtonQPressed(self):
#This is executed when the button is pressed
print('buttonB pressed' *5)
pippo=quitto()
pippo.show()
app = QtWidgets.QApplication(sys.argv)
window=menu()
app.exec_()
if __name__ == '__main__':
和main.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>600</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<property name="windowIcon">
<iconset resource="resource001.qrc">
<normaloff>:/main/python.png</normaloff>
<normalon>:/main/python.png</normalon>
<disabledoff>:/main/python.png</disabledoff>
<disabledon>:/main/python.png</disabledon>
<activeoff>:/main/python.png</activeoff>
<activeon>:/main/python.png</activeon>
<selectedoff>:/main/python.png</selectedoff>
<selectedon>:/main/python.png</selectedon>:/main/python.png</iconset>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #9de650;
}
QPushButton:hover{
background-color: green;
}
QPushButton#ButtonQ{
background-color: orange;
}
QPushButton#ButtonQ:hover{
background-color: red;
}</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>20</x>
<y>0</y>
<width>471</width>
<height>71</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>16</pointsize>
<weight>75</weight>
<bold>true</bold>
<underline>true</underline>
</font>
</property>
<property name="text">
<string>House-Buying-Menu</string>
</property>
<property name="alignment">
<set>Qt::AlignCenter</set>
</property>
</widget>
<widget class="QPushButton" name="ButtonA">
<property name="geometry">
<rect>
<x>170</x>
<y>100</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>A</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonB">
<property name="geometry">
<rect>
<x>170</x>
<y>210</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>B</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonC">
<property name="geometry">
<rect>
<x>170</x>
<y>320</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>C</string>
</property>
</widget>
<widget class="QPushButton" name="ButtonQ">
<property name="geometry">
<rect>
<x>170</x>
<y>450</y>
<width>151</width>
<height>81</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>20</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="text">
<string>QUIT</string>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>520</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources>
<include location="resource001.qrc"/>
</resources>
<connections/>
</ui>
和mainexit.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>MainWindow</class>
<widget class="QMainWindow" name="MainWindow">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>631</width>
<height>496</height>
</rect>
</property>
<property name="windowTitle">
<string>MainWindow</string>
</property>
<widget class="QWidget" name="centralwidget">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="geometry">
<rect>
<x>200</x>
<y>310</y>
<width>174</width>
<height>33</height>
</rect>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</widget>
<widget class="QMenuBar" name="menubar">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>631</width>
<height>29</height>
</rect>
</property>
</widget>
<widget class="QStatusBar" name="statusbar"/>
</widget>
<resources/>
<connections/>
</ui>
该行为的原因是您正在创建的 quitto
实例是 "garbage collected"。像许多高级语言一样,Python 有一个自动管理内存的系统,并负责释放它 "decides" 不再有用的对象的内存。
在函数内创建的任何局部变量总是在函数 returns 后立即删除,除非它以某种方式引用到持久对象。
下面的例子用更简单的方式解释了它:"my_variable"是在function
中创建的,但是一旦它完成(它returns)python就会删除那个变量,这很好,因为如果不这样做,你很容易就会内存不足:
class DeletingObject(object):
'''
A basic class that prints a message whenever any of its instances
is going to be deleted.
'''
def __del__(self):
print('Goodbye cruel world...')
def function():
my_variable = DeletingObject()
print(my_variable)
>>> function()
<__main__.DeletingObject object at 0xb593a46c>
Goodbye cruel world...
同样的事情发生在你的情况下:你创建了 quitto
,但是没有它的永久引用,所以一旦创建它的函数 returns,它就被删除了。
当您在 class 中创建对象时,避免这种情况的最常见方法是使新对象成为 实例属性 :
def QPushButtonQPressed(self):
<b>self.pippo</b> = quitto()
self.pippo.show()
现在新对象不再被删除,window也不会再被销毁
由于您刚刚开始研究所有这些,我想分享一些关于您的示例的建议:
- classes 不应在函数内声明;在某些情况下可以这样做,但它们是非常特殊的情况,通常不需要通用用法(主要原因是 classes 应该可以从任何地方访问,以便可以随时创建它们的实例,但也是因为在函数中定义一个class意味着每次函数都是运行时总是声明它,这对性能来说不是很好);
- 仅在分隔代码的逻辑片段时才在函数中使用空行,而不是在每一行之间;
- 大多数语言的共同约定是对 classes 使用大写名称,对函数、变量和实例使用小写名称,请阅读官方 style guide for Python(a.k.a.PEP-8);
- 虽然从技术上讲它没有任何问题,但通常最好不要混合从模块导入的方式,尤其是当有多个级别的子模块时(例如 PyQt):您要么像在第一行 (
from PyQt5 import QtWidgets
) 或您将要使用的单个 classes,就像您在第二次导入时所做的那样 (from PyQt5.QtWidgets import QDesktopWidget
);第二种方法通常适用于简单的情况,但如果您的代码增长很多,您可能会发现自己有数十个 class 必须手动导入,虽然您可以from PyQt5.QtWidgets import *
通常更好导入子模块并从那里访问 classes:
from PyQt5 import QtWidgets
# ...
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
- QDesktopWidget 已过时,请改用 QScreen;
@musicamante 感谢您详尽详尽的 post(我投了赞成票,但不算数,对不起)不确定我是否必须再 post 关于下一个问题,但它是相关的到上面的那个。我一直在努力让我的脚本正常工作,结果是:
test2.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Created on Wed Apr 8 14:25:12 2020
@author: Pietro
"""
import sys
from PyQt5 import QtWidgets, uic
#import resource
def main():
class Quitto(QtWidgets.QDialog):
def quitbuttonboxquit(self):
print('system exit')
app.quit()
def quitbuttonboxnonquit(self):
print('return to main')
window.show()
self.close()
def __init__(self):
super(Quitto, self).__init__()
uic.loadUi('exitdialog2.ui', self)
self.center()
self.show()
print('inside quitting2 ' *5)
self.QuitbuttonBox.accepted.connect(self.quitbuttonboxquit)
self.QuitbuttonBox.rejected.connect(self.quitbuttonboxnonquit)
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def closeEvent(self, event):
event.ignore()
class Menu(QtWidgets.QMainWindow):
def __init__(self):
super(Menu, self).__init__()
uic.loadUi('main.ui', self)
self.ButtonQ.clicked.connect(self.qpushbuttonqpressed)
self.center()
self.show()
def center(self):
qr = self.frameGeometry()
cp = QtWidgets.QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def qpushbuttonqpressed(self): #This is executed when the button is pressed
print('buttonB pressed' *5)
window.hide()
pippo=Quitto()
pippo.exec_()
def closeEvent(self, event): #Your desired functionality here
event.ignore()
app = QtWidgets.QApplication(sys.argv)
sshFile="coffee.qss"
with open(sshFile,"r") as fh:
app.setStyleSheet(fh.read())
window=Menu()
app.exec_()
if __name__ == '__main__':
main()
和exitdialog.ui
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Dialog</class>
<widget class="QDialog" name="Dialog">
<property name="windowModality">
<enum>Qt::WindowModal</enum>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>586</width>
<height>522</height>
</rect>
</property>
<property name="font">
<font>
<italic>true</italic>
</font>
</property>
<property name="windowTitle">
<string>Dialog</string>
</property>
<property name="styleSheet">
<string notr="true"/>
</property>
<widget class="QDialogButtonBox" name="QuitbuttonBox">
<property name="geometry">
<rect>
<x>40</x>
<y>460</y>
<width>341</width>
<height>32</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QPushButton{
background-color: #17eb3e;
}
QPushButton:hover{
background-color: red;
}
</string>
</property>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
<widget class="QLabel" name="label">
<property name="geometry">
<rect>
<x>50</x>
<y>30</y>
<width>491</width>
<height>341</height>
</rect>
</property>
<property name="styleSheet">
<string notr="true">image: url(:/main/alert.png);</string>
</property>
<property name="text">
<string/>
</property>
</widget>
<widget class="QLabel" name="label_2">
<property name="geometry">
<rect>
<x>170</x>
<y>400</y>
<width>271</width>
<height>41</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>18</pointsize>
<weight>75</weight>
<italic>false</italic>
<bold>true</bold>
</font>
</property>
<property name="styleSheet">
<string notr="true">QLabel {
color : red
}</string>
</property>
<property name="text">
<string>Are you sure to Quit ?!?</string>
</property>
</widget>
</widget>
<resources>
<include location="resource001.qrc"/>
</resources>
<connections>
<connection>
<sender>QuitbuttonBox</sender>
<signal>accepted()</signal>
<receiver>Dialog</receiver>
<slot>accept()</slot>
<hints>
<hint type="sourcelabel">
<x>248</x>
<y>254</y>
</hint>
<hint type="destinationlabel">
<x>157</x>
<y>274</y>
</hint>
</hints>
</connection>
<connection>
<sender>QuitbuttonBox</sender>
<signal>rejected()</signal>
<receiver>Dialog</receiver>
<slot>reject()</slot>
<hints>
<hint type="sourcelabel">
<x>316</x>
<y>260</y>
</hint>
<hint type="destinationlabel">
<x>286</x>
<y>274</y>
</hint>
</hints>
</connection>
</connections>
</ui>
稍后我将尝试拆分函数和 classes(首先我需要弄清楚 classes) 尽管如此,我还是将 class Quitto 更改为 :
class Quitto(QtWidgets.QDialog)
并更改:
def qpushbuttonqpressed(self): #This is executed when the button is pressed
print('buttonB pressed' *5)
window.hide()
pippo=Quitto()
pippo.exec_()
在之前的脚本中使用:
-- window.hide() 在短暂显示两个 windows
后关闭了所有内容同时使用
-- pippo.exec() 而不是 pippo.show() 在
之上显示了新的第二个 window其他,关闭它们后我得到了:
AttributeError: 'quitto' object has no attribute 'exec_'
在第二个脚本中使用 pippo.show() 也没有用,但是 pippo.exe_() 做了
技巧。它如何绕过垃圾收集???
以及为什么将 class Quitto() 更改为 QtWidgets.QMainWindow 我收到属性错误?
在我的项目中,我使用它从主 window 打开另一个 window。我粘贴了具有额外中心功能的全功能脚本,将 main windows 放在屏幕中间。从 Designer 创建两个文件,“UIMain.ui”(主 windows)和第二个 window“notes.ui”并保存它们。
# Open Second Window/Dialog/Form from Main Window
from PyQt5 import uic
from PyQt5.QtWidgets import (
QMainWindow,
QApplication,
QDesktopWidget
)
form_2, base_2 = uic.loadUiType('notes.ui')
class MainNotes(base_2, form_2):
def __init__(self, parent=None):
super(base_2, self).__init__(parent)
self.setupUi(self)
class MainApp(QMainWindow):
""" Main Class
"""
def __init__(self):
super(MainApp, self).__init__()
self.mainnotes = MainNotes()
self.ui = uic.loadUi('UIMain.ui', self)
self.initapp()
def initapp(self):
self.ui.bt_notes.clicked.connect(self.notes)
def notes(self):
"""
Put your code here
"""
self.mainnotes.show()
def center(self):
qr = self.frameGeometry()
cp = QDesktopWidget().availableGeometry().center()
qr.moveCenter(cp)
self.move(qr.topLeft())
def main():
import sys
try:
myapp = QApplication([])
mywindow = MainApp()
mywindow.center()
mywindow.show()
myapp.exec_()
except SystemExit:
sys.exit(0)
if __name__ == '__main__':
main()