- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
本文通过python3+pyqt5实现《python qt gui 快速编程》这本书的page designer应用程序,采用qgraphicsview,qgraphicsscene,qgraphicsitem,这个程序包含有多个文本,图片和框的页面。有些图形类在pyqt5已过时,所以本代码改动幅度比较大。主要的类或方法的改变如下:
qmatrix==>qtransform setmatrix==>settransform rotate ==> setrotation 。
本例中,由于event.delta()已过时,还重写了wheelevent方法:
1
2
3
4
5
6
7
8
9
|
def
wheelevent(
self
, event):
#factor = 1.41 ** (-event.delta() / 240.0)
#factor = 1.41 ** (-abs(event.startx()-event.y()) / 240.0)
factor
=
event.angledelta().y()
/
120.0
if
event.angledelta().y()
/
120.0
>
0
:
factor
=
2
else
:
factor
=
0.5
self
.scale(factor, factor)
|
为了保持代码可读行,增加了一个类:
1
2
3
|
class
graphicspixmapitem(qgraphicspixmapitem):
#add by yangrongdong
def
__init__(
self
,pixmap):
super
(qgraphicspixmapitem,
self
).__init__(pixmap)
|
本例中还有包含菜单的按钮:
1
2
3
4
5
6
7
8
9
10
11
|
if
text
=
=
"&align"
:
menu
=
qmenu(
self
)
for
text, arg
in
(
(
"align &left"
, qt.alignleft),
(
"align &right"
, qt.alignright),
(
"align &top"
, qt.aligntop),
(
"align &bottom"
, qt.alignbottom)):
wrapper
=
functools.partial(
self
.setalignment, arg)
self
.wrapped.append(wrapper)
menu.addaction(text, wrapper)
button.setmenu(menu)
|
本例中还针对qstyleoptiongraphicsitem.levelofdetail已过时,改写如下:
option.levelofdetailfromtransform(self.transform()) 。
下面为完整的代码:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
|
#!/usr/bin/env python3
import
functools
import
random
import
sys
from
pyqt5.qtcore
import
(qbytearray, qdatastream, qfile, qfileinfo,
qiodevice, qpoint, qpointf, qrectf, qt)
from
pyqt5.qtwidgets
import
(qapplication, qdialog,
qdialogbuttonbox, qfiledialog, qfontcombobox,
qgraphicsitem, qgraphicspixmapitem,
qgraphicsscene, qgraphicstextitem, qgraphicsview, qgridlayout,
qhboxlayout, qlabel, qmenu, qmessagebox,qpushbutton, qspinbox,
qstyle, qtextedit, qvboxlayout)
from
pyqt5.qtgui
import
qfont,qcursor,qfontmetrics,qtransform,qpainter,qpen,qpixmap
from
pyqt5.qtprintsupport
import
qprinter,qprintdialog
mac
=
true
try
:
from
pyqt5.qtgui
import
qt_mac_set_native_menubar
except
importerror:
mac
=
false
#pagesize = (595, 842) # a4 in points
pagesize
=
(
612
,
792
)
# us letter in points
pointsize
=
10
magicnumber
=
0x70616765
fileversion
=
1
dirty
=
false
class
textitemdlg(qdialog):
def
__init__(
self
, item
=
none, position
=
none, scene
=
none, parent
=
none):
super
(qdialog,
self
).__init__(parent)
self
.item
=
item
self
.position
=
position
self
.scene
=
scene
self
.editor
=
qtextedit()
self
.editor.setacceptrichtext(false)
self
.editor.settabchangesfocus(true)
editorlabel
=
qlabel(
"&text:"
)
editorlabel.setbuddy(
self
.editor)
self
.fontcombobox
=
qfontcombobox()
self
.fontcombobox.setcurrentfont(qfont(
"times"
, pointsize))
fontlabel
=
qlabel(
"&font:"
)
fontlabel.setbuddy(
self
.fontcombobox)
self
.fontspinbox
=
qspinbox()
self
.fontspinbox.setalignment(qt.alignright|qt.alignvcenter)
self
.fontspinbox.setrange(
6
,
280
)
self
.fontspinbox.setvalue(pointsize)
fontsizelabel
=
qlabel(
"&size:"
)
fontsizelabel.setbuddy(
self
.fontspinbox)
self
.buttonbox
=
qdialogbuttonbox(qdialogbuttonbox.ok|
qdialogbuttonbox.cancel)
self
.buttonbox.button(qdialogbuttonbox.ok).setenabled(false)
if
self
.item
is
not
none:
self
.editor.setplaintext(
self
.item.toplaintext())
self
.fontcombobox.setcurrentfont(
self
.item.font())
self
.fontspinbox.setvalue(
self
.item.font().pointsize())
layout
=
qgridlayout()
layout.addwidget(editorlabel,
0
,
0
)
layout.addwidget(
self
.editor,
1
,
0
,
1
,
6
)
layout.addwidget(fontlabel,
2
,
0
)
layout.addwidget(
self
.fontcombobox,
2
,
1
,
1
,
2
)
layout.addwidget(fontsizelabel,
2
,
3
)
layout.addwidget(
self
.fontspinbox,
2
,
4
,
1
,
2
)
layout.addwidget(
self
.buttonbox,
3
,
0
,
1
,
6
)
self
.setlayout(layout)
self
.fontcombobox.currentfontchanged.connect(
self
.updateui)
self
.fontspinbox.valuechanged.connect(
self
.updateui)
self
.editor.textchanged.connect(
self
.updateui)
self
.buttonbox.accepted.connect(
self
.accept)
self
.buttonbox.rejected.connect(
self
.reject)
self
.setwindowtitle(
"page designer - {0} text item"
.
format
(
"add"
if
self
.item
is
none
else
"edit"
))
self
.updateui()
def
updateui(
self
):
font
=
self
.fontcombobox.currentfont()
font.setpointsize(
self
.fontspinbox.value())
self
.editor.document().setdefaultfont(font)
self
.buttonbox.button(qdialogbuttonbox.ok).setenabled(
bool
(
self
.editor.toplaintext()))
def
accept(
self
):
if
self
.item
is
none:
self
.item
=
textitem("",
self
.position,
self
.scene)
font
=
self
.fontcombobox.currentfont()
font.setpointsize(
self
.fontspinbox.value())
self
.item.setfont(font)
self
.item.setplaintext(
self
.editor.toplaintext())
self
.item.update()
global
dirty
dirty
=
true
qdialog.accept(
self
)
class
textitem(qgraphicstextitem):
def
__init__(
self
, text, position, scene,
font
=
qfont(
"times"
, pointsize), matrix
=
qtransform()):
super
(textitem,
self
).__init__(text)
self
.setflags(qgraphicsitem.itemisselectable|
qgraphicsitem.itemismovable)
self
.setfont(font)
self
.setpos(position)
self
.settransform(matrix)
scene.clearselection()
scene.additem(
self
)
self
.setselected(true)
global
dirty
dirty
=
true
def
parentwidget(
self
):
return
self
.scene().views()[
0
]
def
itemchange(
self
, change, variant):
if
change !
=
qgraphicsitem.itemselectedchange:
global
dirty
dirty
=
true
return
qgraphicstextitem.itemchange(
self
, change, variant)
def
mousedoubleclickevent(
self
, event):
dialog
=
textitemdlg(
self
,
self
.parentwidget())
dialog.exec_()
class
graphicspixmapitem(qgraphicspixmapitem):
#add by yangrongdong
def
__init__(
self
,pixmap):
super
(qgraphicspixmapitem,
self
).__init__(pixmap)
class
boxitem(qgraphicsitem):
def
__init__(
self
, position, scene, style
=
qt.solidline,
rect
=
none, matrix
=
qtransform()):
super
(boxitem,
self
).__init__()
self
.setflags(qgraphicsitem.itemisselectable|
qgraphicsitem.itemismovable|
qgraphicsitem.itemisfocusable)
if
rect
is
none:
rect
=
qrectf(
-
10
*
pointsize,
-
pointsize,
20
*
pointsize,
2
*
pointsize)
self
.rect
=
rect
self
.style
=
style
self
.setpos(position)
self
.settransform(matrix)
scene.clearselection()
scene.additem(
self
)
self
.setselected(true)
self
.setfocus()
global
dirty
dirty
=
true
def
parentwidget(
self
):
return
self
.scene().views()[
0
]
def
boundingrect(
self
):
return
self
.rect.adjusted(
-
2
,
-
2
,
2
,
2
)
def
paint(
self
, painter, option, widget):
pen
=
qpen(
self
.style)
pen.setcolor(qt.black)
pen.setwidth(
1
)
if
option.state & qstyle.state_selected:
pen.setcolor(qt.blue)
painter.setpen(pen)
painter.drawrect(
self
.rect)
def
itemchange(
self
, change, variant):
if
change !
=
qgraphicsitem.itemselectedchange:
global
dirty
dirty
=
true
return
qgraphicsitem.itemchange(
self
, change, variant)
def
contextmenuevent(
self
, event):
wrapped
=
[]
menu
=
qmenu(
self
.parentwidget())
for
text, param
in
(
(
"&solid"
, qt.solidline),
(
"&dashed"
, qt.dashline),
(
"d&otted"
, qt.dotline),
(
"d&ashdotted"
, qt.dashdotline),
(
"dashdo&tdotted"
, qt.dashdotdotline)):
wrapper
=
functools.partial(
self
.setstyle, param)
wrapped.append(wrapper)
menu.addaction(text, wrapper)
menu.exec_(event.screenpos())
def
setstyle(
self
, style):
self
.style
=
style
self
.update()
global
dirty
dirty
=
true
def
keypressevent(
self
, event):
factor
=
pointsize
/
4
changed
=
false
if
event.modifiers() & qt.shiftmodifier:
if
event.key()
=
=
qt.key_left:
self
.rect.setright(
self
.rect.right()
-
factor)
changed
=
true
elif
event.key()
=
=
qt.key_right:
self
.rect.setright(
self
.rect.right()
+
factor)
changed
=
true
elif
event.key()
=
=
qt.key_up:
self
.rect.setbottom(
self
.rect.bottom()
-
factor)
changed
=
true
elif
event.key()
=
=
qt.key_down:
self
.rect.setbottom(
self
.rect.bottom()
+
factor)
changed
=
true
if
changed:
self
.update()
global
dirty
dirty
=
true
else
:
qgraphicsitem.keypressevent(
self
, event)
class
graphicsview(qgraphicsview):
def
__init__(
self
, parent
=
none):
super
(graphicsview,
self
).__init__(parent)
self
.setdragmode(qgraphicsview.rubberbanddrag)
self
.setrenderhint(qpainter.antialiasing)
self
.setrenderhint(qpainter.textantialiasing)
def
wheelevent(
self
, event):
#factor = 1.41 ** (-event.delta() / 240.0)
factor
=
event.angledelta().y()
/
120.0
if
event.angledelta().y()
/
120.0
>
0
:
factor
=
2
else
:
factor
=
0.5
self
.scale(factor, factor)
class
mainform(qdialog):
def
__init__(
self
, parent
=
none):
super
(mainform,
self
).__init__(parent)
self
.filename
=
""
self
.copieditem
=
qbytearray()
self
.pasteoffset
=
5
self
.prevpoint
=
qpoint()
self
.addoffset
=
5
self
.borders
=
[]
self
.printer
=
qprinter(qprinter.highresolution)
self
.printer.setpagesize(qprinter.letter)
self
.view
=
graphicsview()
self
.scene
=
qgraphicsscene(
self
)
self
.scene.setscenerect(
0
,
0
, pagesize[
0
], pagesize[
1
])
self
.addborders()
self
.view.setscene(
self
.scene)
self
.wrapped
=
[]
# needed to keep wrappers alive
buttonlayout
=
qvboxlayout()
for
text, slot
in
(
(
"add &text"
,
self
.addtext),
(
"add &box"
,
self
.addbox),
(
"add pi&xmap"
,
self
.addpixmap),
(
"&align"
, none),
(
"©"
,
self
.copy),
(
"c&ut"
,
self
.cut),
(
"&paste"
,
self
.paste),
(
"&delete..."
,
self
.delete),
(
"&rotate"
,
self
.rotate),
(
"pri&nt..."
,
self
.print_),
(
"&open..."
,
self
.
open
),
(
"&save"
,
self
.save),
(
"&quit"
,
self
.accept)):
button
=
qpushbutton(text)
if
not
mac:
button.setfocuspolicy(qt.nofocus)
if
slot
is
not
none:
button.clicked.connect(slot)
if
text
=
=
"&align"
:
menu
=
qmenu(
self
)
for
text, arg
in
(
(
"align &left"
, qt.alignleft),
(
"align &right"
, qt.alignright),
(
"align &top"
, qt.aligntop),
(
"align &bottom"
, qt.alignbottom)):
wrapper
=
functools.partial(
self
.setalignment, arg)
self
.wrapped.append(wrapper)
menu.addaction(text, wrapper)
button.setmenu(menu)
if
text
=
=
"pri&nt..."
:
buttonlayout.addstretch(
5
)
if
text
=
=
"&quit"
:
buttonlayout.addstretch(
1
)
buttonlayout.addwidget(button)
buttonlayout.addstretch()
layout
=
qhboxlayout()
layout.addwidget(
self
.view,
1
)
layout.addlayout(buttonlayout)
self
.setlayout(layout)
fm
=
qfontmetrics(
self
.font())
self
.resize(
self
.scene.width()
+
fm.width(
" delete... "
)
+
50
,
self
.scene.height()
+
50
)
self
.setwindowtitle(
"page designer"
)
def
addborders(
self
):
self
.borders
=
[]
rect
=
qrectf(
0
,
0
, pagesize[
0
], pagesize[
1
])
self
.borders.append(
self
.scene.addrect(rect, qt.yellow))
margin
=
5.25
*
pointsize
self
.borders.append(
self
.scene.addrect(
rect.adjusted(margin, margin,
-
margin,
-
margin),
qt.yellow))
def
removeborders(
self
):
while
self
.borders:
item
=
self
.borders.pop()
self
.scene.removeitem(item)
del
item
def
reject(
self
):
self
.accept()
def
accept(
self
):
self
.offersave()
qdialog.accept(
self
)
def
offersave(
self
):
if
(dirty
and
qmessagebox.question(
self
,
"page designer - unsaved changes"
,
"save unsaved changes?"
,
qmessagebox.yes|qmessagebox.no)
=
=
qmessagebox.yes):
self
.save()
def
position(
self
):
point
=
self
.mapfromglobal(qcursor.pos())
if
not
self
.view.geometry().contains(point):
coord
=
random.randint(
36
,
144
)
point
=
qpoint(coord, coord)
else
:
if
point
=
=
self
.prevpoint:
point
+
=
qpoint(
self
.addoffset,
self
.addoffset)
self
.addoffset
+
=
5
else
:
self
.addoffset
=
5
self
.prevpoint
=
point
return
self
.view.maptoscene(point)
def
addtext(
self
):
dialog
=
textitemdlg(position
=
self
.position(),
scene
=
self
.scene, parent
=
self
)
dialog.exec_()
def
addbox(
self
):
boxitem(
self
.position(),
self
.scene)
def
addpixmap(
self
):
path
=
(qfileinfo(
self
.filename).path()
if
self
.filename
else
"."
)
fname,filetype
=
qfiledialog.getopenfilename(
self
,
"page designer - add pixmap"
, path,
"pixmap files (*.bmp *.jpg *.png *.xpm)"
)
if
not
fname:
return
self
.createpixmapitem(qpixmap(fname),
self
.position())
def
createpixmapitem(
self
, pixmap, position, matrix
=
qtransform()):
item
=
graphicspixmapitem(pixmap)
item.setflags(qgraphicsitem.itemisselectable|
qgraphicsitem.itemismovable)
item.setpos(position)
item.settransform(matrix)
self
.scene.clearselection()
self
.scene.additem(item)
item.setselected(true)
global
dirty
dirty
=
true
return
item
def
selecteditem(
self
):
items
=
self
.scene.selecteditems()
if
len
(items)
=
=
1
:
return
items[
0
]
return
none
def
copy(
self
):
item
=
self
.selecteditem()
if
item
is
none:
return
self
.copieditem.clear()
self
.pasteoffset
=
5
stream
=
qdatastream(
self
.copieditem, qiodevice.writeonly)
self
.writeitemtostream(stream, item)
def
cut(
self
):
item
=
self
.selecteditem()
if
item
is
none:
return
self
.copy()
self
.scene.removeitem(item)
del
item
def
paste(
self
):
if
self
.copieditem.isempty():
return
stream
=
qdatastream(
self
.copieditem, qiodevice.readonly)
self
.readitemfromstream(stream,
self
.pasteoffset)
self
.pasteoffset
+
=
5
def
setalignment(
self
, alignment):
# items are returned in arbitrary order
items
=
self
.scene.selecteditems()
if
len
(items) <
=
1
:
return
# gather coordinate data
leftxs, rightxs, topys, bottomys
=
[], [], [], []
for
item
in
items:
rect
=
item.sceneboundingrect()
leftxs.append(rect.x())
rightxs.append(rect.x()
+
rect.width())
topys.append(rect.y())
bottomys.append(rect.y()
+
rect.height())
# perform alignment
if
alignment
=
=
qt.alignleft:
xalignment
=
min
(leftxs)
for
i, item
in
enumerate
(items):
item.moveby(xalignment
-
leftxs[i],
0
)
elif
alignment
=
=
qt.alignright:
xalignment
=
max
(rightxs)
for
i, item
in
enumerate
(items):
item.moveby(xalignment
-
rightxs[i],
0
)
elif
alignment
=
=
qt.aligntop:
yalignment
=
min
(topys)
for
i, item
in
enumerate
(items):
item.moveby(
0
, yalignment
-
topys[i])
elif
alignment
=
=
qt.alignbottom:
yalignment
=
max
(bottomys)
for
i, item
in
enumerate
(items):
item.moveby(
0
, yalignment
-
bottomys[i])
global
dirty
dirty
=
true
def
rotate(
self
):
for
item
in
self
.scene.selecteditems():
item.setrotation(item.rotation()
+
30
)
def
delete(
self
):
items
=
self
.scene.selecteditems()
if
(
len
(items)
and
qmessagebox.question(
self
,
"page designer - delete"
,
"delete {0} item{1}?"
.
format
(
len
(items),
"s"
if
len
(items) !
=
1
else
""),
qmessagebox.yes|qmessagebox.no)
=
=
qmessagebox.yes):
while
items:
item
=
items.pop()
self
.scene.removeitem(item)
del
item
global
dirty
dirty
=
true
def
print_(
self
):
dialog
=
qprintdialog(
self
.printer)
if
dialog.exec_():
painter
=
qpainter(
self
.printer)
painter.setrenderhint(qpainter.antialiasing)
painter.setrenderhint(qpainter.textantialiasing)
self
.scene.clearselection()
self
.removeborders()
self
.scene.render(painter)
self
.addborders()
def
open
(
self
):
self
.offersave()
path
=
(qfileinfo(
self
.filename).path()
if
self
.filename
else
"."
)
fname,filetype
=
qfiledialog.getopenfilename(
self
,
"page designer - open"
, path,
"page designer files (*.pgd)"
)
if
not
fname:
return
self
.filename
=
fname
fh
=
none
try
:
fh
=
qfile(
self
.filename)
if
not
fh.
open
(qiodevice.readonly):
raise
ioerror(
str
(fh.errorstring()))
items
=
self
.scene.items()
while
items:
item
=
items.pop()
self
.scene.removeitem(item)
del
item
self
.addborders()
stream
=
qdatastream(fh)
stream.setversion(qdatastream.qt_5_7)
magic
=
stream.readint32()
if
magic !
=
magicnumber:
raise
ioerror(
"not a valid .pgd file"
)
fileversion
=
stream.readint16()
if
fileversion !
=
fileversion:
raise
ioerror(
"unrecognised .pgd file version"
)
while
not
fh.atend():
self
.readitemfromstream(stream)
except
ioerror as e:
qmessagebox.warning(
self
,
"page designer -- open error"
,
"failed to open {0}: {1}"
.
format
(
self
.filename, e))
finally
:
if
fh
is
not
none:
fh.close()
global
dirty
dirty
=
false
def
save(
self
):
if
not
self
.filename:
path
=
"."
fname,filetype
=
qfiledialog.getsavefilename(
self
,
"page designer - save as"
, path,
"page designer files (*.pgd)"
)
if
not
fname:
return
self
.filename
=
fname
fh
=
none
try
:
fh
=
qfile(
self
.filename)
if
not
fh.
open
(qiodevice.writeonly):
raise
ioerror(
str
(fh.errorstring()))
self
.scene.clearselection()
stream
=
qdatastream(fh)
stream.setversion(qdatastream.qt_5_7)
stream.writeint32(magicnumber)
stream.writeint16(fileversion)
for
item
in
self
.scene.items():
self
.writeitemtostream(stream, item)
except
ioerror as e:
qmessagebox.warning(
self
,
"page designer -- save error"
,
"failed to save {0}: {1}"
.
format
(
self
.filename, e))
finally
:
if
fh
is
not
none:
fh.close()
global
dirty
dirty
=
false
def
readitemfromstream(
self
, stream, offset
=
0
):
type
=
""
position
=
qpointf()
matrix
=
qtransform()
rotateangle
=
0
#add by yangrongdong
type
=
stream.readqstring()
stream >> position >> matrix
if
offset:
position
+
=
qpointf(offset, offset)
if
type
=
=
"text"
:
text
=
""
font
=
qfont()
text
=
stream.readqstring()
stream >> font
rotateangle
=
stream.readfloat()
tx
=
textitem(text, position,
self
.scene, font, matrix)
tx.setrotation(rotateangle)
elif
type
=
=
"box"
:
rect
=
qrectf()
stream >> rect
style
=
qt.penstyle(stream.readint16())
rotateangle
=
stream.readfloat()
bx
=
boxitem(position,
self
.scene, style, rect, matrix)
bx.setrotation(rotateangle)
elif
type
=
=
"pixmap"
:
pixmap
=
qpixmap()
stream >> pixmap
rotateangle
=
stream.readfloat()
px
=
self
.createpixmapitem(pixmap, position, matrix)
px.setrotation(rotateangle)
def
writeitemtostream(
self
, stream, item):
if
isinstance
(item, textitem):
stream.writeqstring(
"text"
)
stream<<item.pos()<< item.transform()
stream.writeqstring(item.toplaintext())
stream<< item.font()
stream.writefloat(item.rotation())
#add by yangrongdong
elif
isinstance
(item, graphicspixmapitem):
stream.writeqstring(
"pixmap"
)
stream << item.pos() << item.transform() << item.pixmap()
stream.writefloat(item.rotation())
#add by yangrongdong
elif
isinstance
(item, boxitem):
stream.writeqstring(
"box"
)
stream<< item.pos() << item.transform() << item.rect
stream.writeint16(item.style)
stream.writefloat(item.rotation())
#add by yangrongdong
app
=
qapplication(sys.argv)
form
=
mainform()
rect
=
qapplication.desktop().availablegeometry()
form.resize(
int
(rect.width()
*
0.6
),
int
(rect.height()
*
0.9
))
form.show()
app.exec_()
|
运行结果 。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我.
原文链接:https://blog.csdn.net/xiaoyangyang20/article/details/60571309 。
最后此篇关于python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序的文章就讲到这里了,如果你想了解更多关于python3+PyQt5图形项的自定义和交互 python3实现page Designer应用程序的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
我是 PHP 新手。我在 WordPress 中遇到了这种语法.该代码的最后一行是做什么的? $page = $_SERVER['REQUEST_URI']; $page = str_replace(
为了清楚起见 - 这是我在这个问题中谈论的盒子的图片: 背景:我为客户构建了一个相对复杂的 WP 网站,它更像是一个 CMS 而不是博客,并且依赖于正在构建的页面层次结构。 (嗯,它们实际上是设置了
GitHub Help显示了 GitHub Pages 的以下选项: gh-pages 分行 主分支 master 分支/docs 文件夹 那么我们可以使用名称不是 master 或 gh-pages
我正在使用 AngularJS 框架为我的前端开发一个 Web 应用程序。对于我的登录页面,我必须阻止用户浏览除登录页面和注册之外的其他页面。但是我现在所做的代码也阻止用户导航到注册页面。以下是我的代
如果不将/1 粘贴到 url 上,是否可以改变 Zend_Paginator 来处理 URL?当前用户转到/aaron/studio。然后用户应该点击页面并开始访问 URL,例如:/aaron/stu
目前,我创建了一个可以生成PDF的系统。 PDF 中的数据来自 MySQL 数据库。现在,我像这样显示数据 第一页:仅显示一条数据。 第二页文字:将显示数据(每页最多 3 个数据) 说得更清楚一点,比
我正在尝试构建我的 ASP.NET MVC 4.5 项目以使用搜索引擎友好的 URL。我正在使用以下路由映射。 routes.MapRoute( name: "Default", ur
我为打印按钮使用了以下代码: Data.str = null; //Data.str = textBox24.Text.ToString(); string s = "select * from te
我们有一个带有两个 View 的单页应用程序(本质上是一个项目列表和所选项目的详细信息页面)。两个 View 都在单独的 html 文件中,我们使用 sammy.js 在页面之间进行转换/导航。在我们
(如果有人需要更多信息或更好的描述,请告诉我) 您好,我从这里添加了 viewPagerLibrary:http://viewpagerindicator.com/#introduction今天在我的
我是网页的新手,刚刚开始学习它。在创建新的 Razor 网站后,当我点击添加新项目时,我会看到可以添加的项目的多个选项。它们是: Layout Page(Razor) 这些类似于Master Page
我正在尝试使用 activeadmin 和 awesome_nested_set 创建页面模型。我一直在试图弄清楚如何使用正确的尾随 slug(例如/page1/page1subpage/a-subp
我正在尝试将 DotNetOpenAuth 与 Razor/MVC3 一起使用。大多数 DotNetOpenAuth HTML 助手都接受 System.Web.UI.Page 作为参数之一,使用 W
在我们的应用程序中,当我们在某些页面之间导航时,我们会在进入下一页之前发出服务器请求。发生这种情况时,当前页面上会显示加载图形。奇怪的是,在等待服务器响应完成时,下一页的样式会应用到当前页面。这会导致
我正在使用 ASP.NET Core 3.1 MVC 和 Razor 页面构建 Web 应用程序。 我是 Razor 页面的新手。 我使用上面的方法创建了一个基本应用程序。我想在应用程序启动时加载登录
我遇到了一个我似乎无法解释的问题。我在 Umbraco 中设置了一个主模板和 2 个子模板,但出现以下错误: Content controls have to be top-level control
我正在创建一个网络应用程序,允许用户选择他们当前的部门、他们将临时借调到哪个部门、他们正在执行的任务以及在任务上花费的时间。我需要写一些声明,根据他们当前部门的选择来确定他们所在的团队(当前的或新的)
当我导航到一个页面时,我得到了404错误页面,该页面说,在我刷新浏览器之前,没有包含此URL的页面,然后该页面才会显示。。我尝试使用@REACH/ROUTER来导航,而不是使用REACT-ROUTER
我正在使用 Html2Pdf 将一些 HTML 文件转换为 PDF。我还需要添加分页符来划分文档的各个部分。为此,我使用 标签。 我有以下 HTML 片段: ...
我正在使用另一个静态网站生成器,我希望能够将源文件(以markdown格式)以及生成的网站 checkin 到我的username.github.com存储库中。因此,很像Jekyll,但我没有使用J
我是一名优秀的程序员,十分优秀!