index.lxp@lxpwrap=x1214_252ehtm.htm
来自「GUI Programming with Python」· HTM 代码 · 共 461 行
HTM
461 行
<table border="0" cellspacing="0" cellpadding="3" width="100%"><tr><td> <div align="center" id="bldcontent"> <a href="../default.htm"><img src="../images/opendocs.png" width="63" height="76" border="0"></a> <br> <div class="symbol">Your OpenSource Publisher™</div> </div> </td></tr></table> <div align="center" class="author"> <a href="../products.lxp">Products</a> | <a href="../wheretobuy.lxp">Where to buy</a> | <a href="../bookstore.lxp">Retailers</a> | <a href="../faq.lxp">FAQ</a> | <a href="../writeforus.lxp">Write for Us.</a> | <a href="#contact">Contact Us.</a> </div> <table border="0" cellspacing="3" cellpadding="0" width="100%"><tr><td width="100%"> <div class="content"> <table border="0" cellspacing="2" cellpadding="0" width="100%"><tr><td width="100%"> <div align="center"><H4 CLASS="AUTHOR"><A NAME="AEN5">Boudewijn Rempt</A><br><a href="../../https@secure.linuxports.com/opendocs/default.htm"><img src=odpyqt125.png></a><br>ISBN: 0-97003300-4-4<br><a href="../../https@secure.linuxports.com/opendocs/default.htm">Available from bookstores everywhere or you can order it here.</a><p>You can download the source files for the book <a href="pyqtsrc.tgz">(code / eps) here.</a><hr></div> <HTML><HEAD><TITLE>Designing forms</TITLE><METANAME="GENERATOR"CONTENT="Modular DocBook HTML Stylesheet Version 1.72"><LINKREL="HOME"TITLE="GUI Programming with Python: QT Edition"HREF="book1.htm"><LINKREL="UP"TITLE="Qt Concepts"HREF="c1036.htm"><LINKREL="PREVIOUS"TITLE=" A better Hello World "HREF="x1149.htm"><LINKREL="NEXT"TITLE="Conclusion"HREF="x1263.htm"></HEAD><BODYCLASS="SECT1"BGCOLOR="#FFFFFF"TEXT="#000000"LINK="#0000FF"VLINK="#840084"ALINK="#0000FF"><DIVCLASS="NAVHEADER"><TABLESUMMARY="Header navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><THCOLSPAN="3"ALIGN="center">GUI Programming with Python: QT Edition</TH></TR><TR><TDWIDTH="10%"ALIGN="left"VALIGN="bottom"><A accesskey="P" href="index.lxp@lxpwrap=x1149_252ehtm.htm">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom">Chapter 6. Qt Concepts</TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><A accesskey="N" href="index.lxp@lxpwrap=x1263_252ehtm.htm">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="SECT1"><H1CLASS="SECT1">Designing forms</A></H1><P>One important feature of BlackAdder and PyQt is the visual gui designer. You can use the designer to easily create all kinds of dialog windows, and even custom widgets.</P><P>The definition of these user-interface designs is saved in files in an XML format, and you can easily translate those to Python code. The beauty of the system is that you can just as easily translate your designs to valid C++ code, making it easy to develop your prototype in Python and, when satisfied, port the whole gui to fast, compiled C++. (C++ code, I might add, that compiles just as well on Windows, Unix/X11, OS X and embedded systems).</P><P>The version of Qt Designer that is included with Qt3 can also create complete main windows with menus and toolbars. Once <SPANCLASS="APPLICATION">pyuic</SPAN> has been updated to include those elements, you can use this in your Python projects, too.</P><P>Let's use Designer to design a small form that would be useful for connecting to some system, and hook it up in a small PyQt program.</P><DIVCLASS="MEDIAOBJECT"><P><DIVCLASS="CAPTION"><P>A form in the gui designer</P></DIV></P></DIV><P>It's quite easy to work with designer — just keep in mind that you <SPAN><ICLASS="EMPHASIS">never</I></SPAN> have to place items pixel-perfect. Just bang widgets of roughly the right size in roughly the right places, add the Qt layout managers, and see them work their magic. </P><P>You add a layout manager by selecting the widgets you want to be managed, and then selecting the right layout manager from the toolbar.</P><P>In the above design, there are three layout managers: the buttons on the right are stacked, the widgets inside the bevel are in a grid, and everything in the form is in another grid. Try making the dialog larger and smaller — it will always look good. Even better, if a visually impaired user chooses a large system font, say Arial 24 points bold, the form will still look good.</P><P>You can either compile the .ui file to Python code from BlackAdder or from the command-line. The result will be something like this:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 6-6. frmconnect.py</B></P><PRECLASS="PROGRAMLISTING"># Form implementation generated from reading ui file 'frmconnect.ui'## Created: Wed Feb 28 21:34:40 2001# by: The Python User Interface Compiler (pyuic)## WARNING! All changes made in this file will be lost!from qt import *class frmConnect(QDialog): def __init__(self,parent = None,name = None,modal = 0,fl = 0): QDialog.__init__(self,parent,name,modal,fl) if name == None: self.setName('frmConnect') self.resize(547,140) self.setCaption(self.tr('Connecting')) self.setSizeGripEnabled(1) frmConnectLayout = QGridLayout(self) frmConnectLayout.setSpacing(6) frmConnectLayout.setMargin(11) Layout5 = QVBoxLayout() Layout5.setSpacing(6) Layout5.setMargin(0) self.buttonOk = QPushButton(self,'buttonOk') self.buttonOk.setText(self.tr('&OK')) self.buttonOk.setAutoDefault(1) self.buttonOk.setDefault(1) Layout5.addWidget(self.buttonOk) self.buttonCancel = QPushButton(self,'buttonCancel') self.buttonCancel.setText(self.tr('&Cancel')) self.buttonCancel.setAutoDefault(1) Layout5.addWidget(self.buttonCancel) self.buttonHelp = QPushButton(self,'buttonHelp') self.buttonHelp.setText(self.tr('&Help')) self.buttonHelp.setAutoDefault(1) Layout5.addWidget(self.buttonHelp) spacer = QSpacerItem(20,20,QSizePolicy.Minimum,QSizePolicy.Expanding) Layout5.addItem(spacer) frmConnectLayout.addLayout(Layout5,0,1) self.grpConnection = QGroupBox(self,'grpConnection') self.grpConnection.setSizePolicy(QSizePolicy(5,7,self.grpConnection. \ sizePolicy().hasHeightForWidth())) self.grpConnection.setTitle(self.tr('')) self.grpConnection.setColumnLayout(0,Qt.Vertical) self.grpConnection.layout().setSpacing(0) self.grpConnection.layout().setMargin(0) grpConnectionLayout = QGridLayout(self.grpConnection.layout()) grpConnectionLayout.setAlignment(Qt.AlignTop) grpConnectionLayout.setSpacing(6) grpConnectionLayout.setMargin(11) self.lblName = QLabel(self.grpConnection,'lblName') self.lblName.setText(self.tr('&Name')) grpConnectionLayout.addWidget(self.lblName,0,0) self.lblHost = QLabel(self.grpConnection,'lblHost') self.lblHost.setText(self.tr('&Host')) grpConnectionLayout.addWidget(self.lblHost,2,0) self.lblPasswd = QLabel(self.grpConnection,'lblPasswd') self.lblPasswd.setText(self.tr('&Password')) grpConnectionLayout.addWidget(self.lblPasswd,1,0) self.txtPasswd = QLineEdit(self.grpConnection,'txtPasswd') self.txtPasswd.setMaxLength(8) self.txtPasswd.setEchoMode(QLineEdit.Password) grpConnectionLayout.addWidget(self.txtPasswd,1,1) self.cmbHostnames = QComboBox(0,self.grpConnection,'cmbHostnames') grpConnectionLayout.addWidget(self.cmbHostnames,2,1) self.txtName = QLineEdit(self.grpConnection,'txtName') self.txtName.setMaxLength(8) grpConnectionLayout.addWidget(self.txtName,0,1) frmConnectLayout.addWidget(self.grpConnection,0,0) self.connect(self.buttonOk,SIGNAL('clicked()'),self,SLOT('accept()')) self.connect(self.buttonCancel,SIGNAL('clicked()'), \ self,SLOT('reject()')) self.setTabOrder(self.txtName,self.txtPasswd) self.setTabOrder(self.txtPasswd,self.cmbHostnames) self.setTabOrder(self.cmbHostnames,self.buttonOk) self.setTabOrder(self.buttonOk,self.buttonCancel) self.setTabOrder(self.buttonCancel,self.buttonHelp) self.lblName.setBuddy(self.txtName) self.lblPasswd.setBuddy(self.txtName) </PRE></DIV><P>Now this looks pretty hideous — but fortunately you'll never have to hack it. You would lose all your changes anyway, the next time you make a change to your design and regenerate the Python code. The best thing to do is to subclass this form with code that actually fills the dialog with data and perfoms an action upon closing it. I like to keep the names of the generated form and the subclassed form related, and I tend to refer to the first as a form, and the second as dialog — hence the prefix frmXXX for generated forms and dlgXXX for the dialogs.</P><P>For example:</P><DIVCLASS="EXAMPLE"></A><P><B>Example 6-7. dlgconnect.py — the subclass of the generated form</B></P><PRECLASS="PROGRAMLISTING">import sysfrom qt import *from frmconnect import frmConnectclass dlgConnect(frmConnect): def __init__(self, parent=None): frmConnect.__init__(self, parent) self.txtName.setText("Baldrick") for host in ["elizabeth","george", "melchett"]: self.cmbHostnames.insertItem(host) def accept(self): print self.txtName.text() print self.txtPasswd.text() print self.cmbHostnames.currentText() frmConnect.accept(self)if __name__ == '__main__': app = QApplication(sys.argv) QObject.connect(app, SIGNAL('lastWindowClosed()'), app, SLOT('quit()')) win = dlgConnect() app.setMainWidget(win) win.show() app.exec_loop() </PRE></DIV><P>As you can see, we have subclassed the generated form. In the constructor, the various fields are filled with a bit of data. Note that we can simply use Python string objects in setText() methods. Qt uses a special string object, <TTCLASS="CLASSNAME">QString</TT> for all its textual data, but PyQt automatically translates both Python strings and Python unicode strings to these <TTCLASS="CLASSNAME">QString</TT> objects. There are some complications, which we deal with in <A href="index.lxp@lxpwrap=c2029_252ehtm.htm">Chapter 8</A>, but the translation is mostly transparent.</P><P>When you press the OK button, Qt calls the <TTCLASS="FUNCTION">accept()</TT> method of the dialog class, in this case <TTCLASS="CLASSNAME">dlgConnect</TT>, which inherits <TTCLASS="CLASSNAME">frmConnect</TT>, which inherits <TTCLASS="CLASSNAME">QDialog</TT>. The <TTCLASS="FUNCTION">accept()</TT> method prints out the contents of the fields. Then the <TTCLASS="FUNCTION">accept()</TT> method of the parent class — ultimately <TTCLASS="CLASSNAME">QDialog</TT> — is called, and the dialog is closed.</P></DIV><DIVCLASS="NAVFOOTER"><HRALIGN="LEFT"WIDTH="100%"><TABLESUMMARY="Footer navigation table"WIDTH="100%"BORDER="0"CELLPADDING="0"CELLSPACING="0"><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top"><A accesskey="P" href="index.lxp@lxpwrap=x1149_252ehtm.htm">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="H" href="index.lxp@lxpwrap=book1_252ehtm">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><A accesskey="N" href="index.lxp@lxpwrap=x1263_252ehtm.htm">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">A better Hello World</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><A accesskey="U" href="index.lxp@lxpwrap=c1036_252ehtm.htm">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Conclusion</TD></TR></TABLE></DIV></BODY></HTML> </td> </tr> </table> </td> </tr> </table>
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?