📄 c8016.htm
字号:
<HTML><HEAD><TITLE>Drag and drop</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="Creating real applications with PyQt"HREF="p4627.htm"><LINKREL="PREVIOUS"TITLE="Creating themes with QStyle"HREF="x7947.htm"><LINKREL="NEXT"TITLE="Initiating drags"HREF="x8073.htm"></HEAD><BODYCLASS="CHAPTER"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"><AHREF="x7947.htm"ACCESSKEY="P">Prev</A></TD><TDWIDTH="80%"ALIGN="center"VALIGN="bottom"></TD><TDWIDTH="10%"ALIGN="right"VALIGN="bottom"><AHREF="x8073.htm"ACCESSKEY="N">Next</A></TD></TR></TABLE><HRALIGN="LEFT"WIDTH="100%"></DIV><DIVCLASS="CHAPTER"><H1><ANAME="CH20">Chapter 23. Drag and drop</A></H1><DIVCLASS="TOC"><DL><DT><B>Table of Contents</B></DT><DT><AHREF="c8016.htm#AEN8026">Handling drops</A></DT><DT><AHREF="x8073.htm">Initiating drags</A></DT><DT><AHREF="x8095.htm">Conclusion</A></DT></DL></DIV><P>PyQt fully supports standard drag and drop operations on all platforms. This includes both Windows OLE drag and drop, and the two X11 standards: XDND (which uses MIME) and the legacy Motif Drag'n'Drop protocol.</P><P>MIME, which you may know as a way to encode all kinds of datatypes for e-mail, is used to encode the dragged data in Qt. This is a very flexible standard, regulated by IANA (http://www.isi.edu/in-notes/iana/assignments/media-types/). This means that almost any kind of data can be handled by the Qt drag and drop mechanism, not just text or images.</P><DIVCLASS="SECT1"><H1CLASS="SECT1"><ANAME="AEN8026">Handling drops</A></H1><P>Our <SPANCLASS="APPLICATION">Kalam</SPAN> editor must be able to accepts drops from other applications, so we will have to implement this functionality.</P><P>Incoming drop operations are easy enough to handle. Basically, you call <TTCLASS="FUNCTION">self.setAcceptDrops(TRUE)</TT> for the widget or widgets that should accept drop events, and then actually handle those drop events.</P><P>The widget that <SPAN><ICLASS="EMPHASIS">should</I></SPAN> accept the drops is our <TTCLASS="CLASSNAME">KalamView</TT> class. But setting <TTCLASS="FUNCTION">self.setAcceptDrops(TRUE)</TT> in the constructor of <TTCLASS="CLASSNAME">KalamView</TT> won't work. This is because <TTCLASS="CLASSNAME">KalamView</TT> doesn't actually handle the drops; rather, they are handled by the <TTCLASS="CLASSNAME">QMultiLineEdit</TT> class, which is encapsulated by <TTCLASS="CLASSNAME">KalamView</TT>.</P><P>The easiest solution is to extend the small subclass of <TTCLASS="CLASSNAME">QMultiLineEdit</TT> (which we already created) to handle drop events.</P><DIVCLASS="EXAMPLE"><ANAME="AEN8046"></A><P><B>Example 23-1. Handling drop events</B></P><PRECLASS="PROGRAMLISTING">"""kalamview.py - the editor view component for Kalamcopyright: (C) 2001, Boudewijn Remptemail: boud@rempt.xs4all.nl"""from qt import *import kalamconfigfrom resources import TRUE, FALSEclass KalamMultiLineEdit(QMultiLineEdit): def __init__(self, *args): apply(QMultiLineEdit.__init__,(self,) + args) self.setAcceptDrops(TRUE) def dragEnterEvent(self, e): e.accept(QTextDrag.canDecode(e)) def dropEvent(self, e): t=QString() if QTextDrag.decode(e, t): # fills t with decoded text self.insert(t) self.emit(SIGNAL("textChanged()"), ()) def event(self, e): if e.type() == QEvent.KeyPress: QMultiLineEdit.keyPressEvent(self, e) return TRUE else: return QMultiLineEdit.event(self, e) </PRE></DIV><P>How does this bit of code work? First, you can see that the custom widget accepts drop events: <SPAN><ICLASS="EMPHASIS">self.setAcceptDrops(TRUE)</I></SPAN>.</P><P>The <TTCLASS="FUNCTION">dragEnterEvent()</TT> method is fired whenever something is dragged over the widget. In this function we can determine whether the object that is dragged over our application is something we'd like to accept. If the function <TTCLASS="FUNCTION">QTextDrag.canDecode()</TT> returns true, then we know we can get some text out of the data the drop event carries. We accept the event, which means that whenever the cursor enters the widget, the shape will change to indicate that the contents can be dropped.</P><P>If the user releases the mouse button, the function <TTCLASS="FUNCTION">dropEvent()</TT> is called. This presents us with a <TTCLASS="CLASSNAME">QDropEvent</TT> object, which we can decode to get the contents.</P><P>However, here we come across one of the inconsistencies of the PyQt bindings to Qt. Sometimes a function wants to return two values: a boolean to indicate whether the operation was successful, and the result of the operation. In the case of <TTCLASS="CLASSNAME">QFontDialog</TT>, the results are returned in a tuple:</P><PRECLASS="PROGRAMLISTING"> (font, ok) = QFontDialog.getFont(self, "FontDialog") </PRE><P>Likewise, <TTCLASS="FUNCTION">QTextDrag.decode</TT> wants to return two values: a boolean and a string. However, here you need to first create a <TTCLASS="CLASSNAME">QString</TT>, and pass that to <TTCLASS="FUNCTION">QTextDrag.decode</TT>, which fills it with the text, while returning a boolean indicating whether the decoding went well.</P><P>However, having got the text by hook or by crook, we can insert it in the view, and tell the world that the text has changed (so other views on the text can update themselves).</P><P>You can now select and drag that text to a <SPANCLASS="APPLICATION">Kalam</SPAN> document. If you drag a file, only the filename will be inserted, because a filename can also be decoded as text. If you want to open the file instead, you still have some work to do.</P></DIV></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"><AHREF="x7947.htm"ACCESSKEY="P">Prev</A></TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="book1.htm"ACCESSKEY="H">Home</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top"><AHREF="x8073.htm"ACCESSKEY="N">Next</A></TD></TR><TR><TDWIDTH="33%"ALIGN="left"VALIGN="top">Creating themes with QStyle</TD><TDWIDTH="34%"ALIGN="center"VALIGN="top"><AHREF="p4627.htm"ACCESSKEY="U">Up</A></TD><TDWIDTH="33%"ALIGN="right"VALIGN="top">Initiating drags</TD></TR></TABLE></DIV></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -