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

Last change on this file since 822 was 651, checked in by Dmitry A. Kuminov, 15 years ago

trunk: Merged in qt 4.6.2 sources.

File size: 6.8 KB
Line 
1/****************************************************************************
2**
3** Copyright (C) 2010 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:LGPL$
10** Commercial Usage
11** Licensees holding valid Qt Commercial licenses may use this file in
12** accordance with the Qt Commercial License Agreement provided with the
13** Software or, alternatively, in accordance with the terms contained in
14** a written agreement between you and Nokia.
15**
16** GNU Lesser General Public License Usage
17** Alternatively, this file may be used under the terms of the GNU Lesser
18** General Public License version 2.1 as published by the Free Software
19** Foundation and appearing in the file LICENSE.LGPL included in the
20** packaging of this file. Please review the following information to
21** ensure the GNU Lesser General Public License version 2.1 requirements
22** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
23**
24** In addition, as a special exception, Nokia gives you certain additional
25** rights. These rights are described in the Nokia Qt LGPL Exception
26** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
27**
28** GNU General Public License Usage
29** Alternatively, this file may be used under the terms of the GNU
30** General Public License version 3.0 as published by the Free Software
31** Foundation and appearing in the file LICENSE.GPL included in the
32** packaging of this file. Please review the following information to
33** ensure the GNU General Public License version 3.0 requirements will be
34** met: http://www.gnu.org/copyleft/gpl.html.
35**
36** If you have questions regarding the use of this file, please contact
37** Nokia at [email protected].
38** $QT_END_LICENSE$
39**
40****************************************************************************/
41
42#include "dialog.h"
43#include <QFileDialog>
44#include <QBuffer>
45#include <QtCore/QDebug>
46
47/*!
48 \class Dialog
49
50 \brief This class is a simple example of how to use QSharedMemory.
51
52 It is a simple dialog that presents a few buttons. To compile the
53 example, run make in qt/examples/ipc. Then run the executable twice
54 to create two processes running the dialog. In one of the processes,
55 press the button to load an image into a shared memory segment, and
56 then select an image file to load. Once the first process has loaded
57 and displayed the image, in the second process, press the button to
58 read the same image from shared memory. The second process displays
59 the same image loaded from its new loaction in shared memory.
60*/
61
62/*!
63 The class contains a data member \l {QSharedMemory} {sharedMemory},
64 which is initialized with the key "QSharedMemoryExample" to force
65 all instances of Dialog to access the same shared memory segment.
66 The constructor also connects the clicked() signal from each of the
67 three dialog buttons to the slot function appropriate for handling
68 each button.
69*/
70//! [0]
71Dialog::Dialog(QWidget *parent)
72 : QDialog(parent), sharedMemory("QSharedMemoryExample")
73{
74 ui.setupUi(this);
75 connect(ui.loadFromFileButton, SIGNAL(clicked()), SLOT(loadFromFile()));
76 connect(ui.loadFromSharedMemoryButton,
77 SIGNAL(clicked()),
78 SLOT(loadFromMemory()));
79 setWindowTitle(tr("SharedMemory Example"));
80}
81//! [0]
82
83/*!
84 This slot function is called when the \tt {Load Image From File...}
85 button is pressed on the firs Dialog process. First, it tests
86 whether the process is already connected to a shared memory segment
87 and, if so, detaches from that segment. This ensures that we always
88 start the example from the beginning if we run it multiple times
89 with the same two Dialog processes. After detaching from an existing
90 shared memory segment, the user is prompted to select an image file.
91 The selected file is loaded into a QImage. The QImage is displayed
92 in the Dialog and streamed into a QBuffer with a QDataStream.
93
94 Next, it gets a new shared memory segment from the system big enough
95 to hold the image data in the QBuffer, and it locks the segment to
96 prevent the second Dialog process from accessing it. Then it copies
97 the image from the QBuffer into the shared memory segment. Finally,
98 it unlocks the shared memory segment so the second Dialog process
99 can access it.
100
101 After this function runs, the user is expected to press the \tt
102 {Load Image from Shared Memory} button on the second Dialog process.
103
104 \sa loadFromMemory()
105 */
106//! [1]
107void Dialog::loadFromFile()
108{
109 if (sharedMemory.isAttached())
110 detach();
111
112 ui.label->setText(tr("Select an image file"));
113 QString fileName = QFileDialog::getOpenFileName(0, QString(), QString(),
114 tr("Images (*.png *.xpm *.jpg)"));
115 QImage image;
116 if (!image.load(fileName)) {
117 ui.label->setText(tr("Selected file is not an image, please select another."));
118 return;
119 }
120 ui.label->setPixmap(QPixmap::fromImage(image));
121//! [1] //! [2]
122
123 // load into shared memory
124 QBuffer buffer;
125 buffer.open(QBuffer::ReadWrite);
126 QDataStream out(&buffer);
127 out << image;
128 int size = buffer.size();
129
130 if (!sharedMemory.create(size)) {
131 ui.label->setText(tr("Unable to create shared memory segment."));
132 return;
133 }
134 sharedMemory.lock();
135 char *to = (char*)sharedMemory.data();
136 const char *from = buffer.data().data();
137 memcpy(to, from, qMin(sharedMemory.size(), size));
138 sharedMemory.unlock();
139}
140//! [2]
141
142/*!
143 This slot function is called in the second Dialog process, when the
144 user presses the \tt {Load Image from Shared Memory} button. First,
145 it attaches the process to the shared memory segment created by the
146 first Dialog process. Then it locks the segment for exclusive
147 access, copies the image data from the segment into a QBuffer, and
148 streams the QBuffer into a QImage. Then it unlocks the shared memory
149 segment, detaches from it, and finally displays the QImage in the
150 Dialog.
151
152 \sa loadFromFile()
153 */
154//! [3]
155void Dialog::loadFromMemory()
156{
157 if (!sharedMemory.attach()) {
158 ui.label->setText(tr("Unable to attach to shared memory segment.\n" \
159 "Load an image first."));
160 return;
161 }
162
163 QBuffer buffer;
164 QDataStream in(&buffer);
165 QImage image;
166
167 sharedMemory.lock();
168 buffer.setData((char*)sharedMemory.constData(), sharedMemory.size());
169 buffer.open(QBuffer::ReadOnly);
170 in >> image;
171 sharedMemory.unlock();
172
173 sharedMemory.detach();
174 ui.label->setPixmap(QPixmap::fromImage(image));
175}
176//! [3]
177
178/*!
179 This private function is called by the destructor to detach the
180 process from its shared memory segment. When the last process
181 detaches from a shared memory segment, the system releases the
182 shared memory.
183 */
184void Dialog::detach()
185{
186 if (!sharedMemory.detach())
187 ui.label->setText(tr("Unable to detach from shared memory."));
188}
189
Note: See TracBrowser for help on using the repository browser.