source: trunk/examples/ipc/sharedmemory/dialog.cpp

Last change on this file was 846, checked in by Dmitry A. Kuminov, 14 years ago

trunk: Merged in qt 4.7.2 sources from branches/vendor/nokia/qt.

File size: 6.9 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
4** All rights reserved.
5** Contact: Nokia Corporation ([email protected])
6**
7** This file is part of the examples of the Qt Toolkit.
8**
9** $QT_BEGIN_LICENSE:BSD$
10** You may use this file under the terms of the BSD license as follows:
11**
12** "Redistribution and use in source and binary forms, with or without
13** modification, are permitted provided that the following conditions are
14** met:
15** * Redistributions of source code must retain the above copyright
16** notice, this list of conditions and the following disclaimer.
17** * Redistributions in binary form must reproduce the above copyright
18** notice, this list of conditions and the following disclaimer in
19** the documentation and/or other materials provided with the
20** distribution.
21** * Neither the name of Nokia Corporation and its Subsidiary(-ies) nor
22** the names of its contributors may be used to endorse or promote
23** products derived from this software without specific prior written
24** permission.
25**
26** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
27** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
28** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
29** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
30** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
31** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
32** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
33** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
34** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
35** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
36** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
37** $QT_END_LICENSE$
38**
39****************************************************************************/
40
41#include "dialog.h"
42#include <QFileDialog>
43#include <QBuffer>
44#include <QtCore/QDebug>
45
46/*!
47 \class Dialog
48
49 \brief This class is a simple example of how to use QSharedMemory.
50
51 It is a simple dialog that presents a few buttons. To compile the
52 example, run make in qt/examples/ipc. Then run the executable twice
53 to create two processes running the dialog. In one of the processes,
54 press the button to load an image into a shared memory segment, and
55 then select an image file to load. Once the first process has loaded
56 and displayed the image, in the second process, press the button to
57 read the same image from shared memory. The second process displays
58 the same image loaded from its new loaction in shared memory.
59*/
60
61/*!
62 The class contains a data member \l {QSharedMemory} {sharedMemory},
63 which is initialized with the key "QSharedMemoryExample" to force
64 all instances of Dialog to access the same shared memory segment.
65 The constructor also connects the clicked() signal from each of the
66 three dialog buttons to the slot function appropriate for handling
67 each button.
68*/
69//! [0]
70Dialog::Dialog(QWidget *parent)
71 : QDialog(parent), sharedMemory("QSharedMemoryExample")
72{
73 ui.setupUi(this);
74 connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile()));
75 connect(ui.loadFromSharedMemoryButton,
76 SIGNAL(clicked()),
77 SLOT(loadFromMemory()));
78 setWindowTitle(tr("SharedMemory Example"));
79}
80//! [0]
81
82/*!
83 This slot function is called when the \tt {Load Image From File...}
84 button is pressed on the firs Dialog process. First, it tests
85 whether the process is already connected to a shared memory segment
86 and, if so, detaches from that segment. This ensures that we always
87 start the example from the beginning if we run it multiple times
88 with the same two Dialog processes. After detaching from an existing
89 shared memory segment, the user is prompted to select an image file.
90 The selected file is loaded into a QImage. The QImage is displayed
91 in the Dialog and streamed into a QBuffer with a QDataStream.
92
93 Next, it gets a new shared memory segment from the system big enough
94 to hold the image data in the QBuffer, and it locks the segment to
95 prevent the second Dialog process from accessing it. Then it copies
96 the image from the QBuffer into the shared memory segment. Finally,
97 it unlocks the shared memory segment so the second Dialog process
98 can access it.
99
100 After this function runs, the user is expected to press the \tt
101 {Load Image from Shared Memory} button on the second Dialog process.
102
103 \sa loadFromMemory()
104 */
105//! [1]
106void Dialog::loadFromFile()
107{
108 if (sharedMemory.isAttached())
109 detach();
110
111 ui.label->setText(tr("Select an image file"));
112 QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(),
113 tr("Images (*.png *.xpm *.jpg)"));
114 QImage image;
115 if (!image.load(fileName)) {
116 ui.label->setText(tr("Selected file is not an image, please select another."));
117 return;
118 }
119 ui.label->setPixmap(QPixmap::fromImage(image));
120//! [1] //! [2]
121
122 // load into shared memory
123 QBuffer buffer;
124 buffer.open(QBuffer::ReadWrite);
125 QDataStream out(&buffer);
126 out << image;
127 int size = buffer.size();
128
129 if (!sharedMemory.create(size)) {
130 ui.label->setText(tr("Unable to create shared memory segment."));
131 return;
132 }
133 sharedMemory.lock();
134 char *to = (char*)sharedMemory.data();
135 const char *from = buffer.data().data();
136 memcpy(to, from, qMin(sharedMemory.size(), size));
137 sharedMemory.unlock();
138}
139//! [2]
140
141/*!
142 This slot function is called in the second Dialog process, when the
143 user presses the \tt {Load Image from Shared Memory} button. First,
144 it attaches the process to the shared memory segment created by the
145 first Dialog process. Then it locks the segment for exclusive
146 access, copies the image data from the segment into a QBuffer, and
147 streams the QBuffer into a QImage. Then it unlocks the shared memory
148 segment, detaches from it, and finally displays the QImage in the
149 Dialog.
150
151 \sa loadFromFile()
152 */
153//! [3]
154void Dialog::loadFromMemory()
155{
156 if (!sharedMemory.attach()) {
157 ui.label->setText(tr("Unable to attach to shared memory segment.\n" \
158 "Load an image first."));
159 return;
160 }
161
162 QBuffer buffer;
163 QDataStream in(&buffer);
164 QImage image;
165
166 sharedMemory.lock();
167 buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
168 buffer.open(QBuffer::ReadOnly);
169 in >> image;
170 sharedMemory.unlock();
171
172 sharedMemory.detach();
173 ui.label->setPixmap(QPixmap::fromImage(image));
174}
175//! [3]
176
177/*!
178 This private function is called by the destructor to detach the
179 process from its shared memory segment. When the last process
180 detaches from a shared memory segment, the system releases the
181 shared memory.
182 */
183void Dialog::detach()
184{
185 if (!sharedMemory.detach())
186 ui.label->setText(tr("Unable to detach from shared memory."));
187}
188
Note: See TracBrowser for help on using the repository browser.