File: el.mo

package info (click to toggle)
gtkmm-documentation 3.12.0-1
  • links: PTS, VCS
  • area: main
  • in suites: jessie, jessie-kfreebsd
  • size: 18,628 kB
  • ctags: 2,376
  • sloc: cpp: 12,615; sh: 1,004; makefile: 808; perl: 57
file content (2543 lines) | stat: -rw-r--r-- 916,638 bytes parent folder | download
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
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
1006
1007
1008
1009
1010
1011
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058
1059
1060
1061
1062
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155
1156
1157
1158
1159
1160
1161
1162
1163
1164
1165
1166
1167
1168
1169
1170
1171
1172
1173
1174
1175
1176
1177
1178
1179
1180
1181
1182
1183
1184
1185
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205
1206
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233
1234
1235
1236
1237
1238
1239
1240
1241
1242
1243
1244
1245
1246
1247
1248
1249
1250
1251
1252
1253
1254
1255
1256
1257
1258
1259
1260
1261
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
1291
1292
1293
1294
1295
1296
1297
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393
1394
1395
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461
1462
1463
1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
1583
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637
1638
1639
1640
1641
1642
1643
1644
1645
1646
1647
1648
1649
1650
1651
1652
1653
1654
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679
1680
1681
1682
1683
1684
1685
1686
1687
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708
1709
1710
1711
1712
1713
1714
1715
1716
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734
1735
1736
1737
1738
1739
1740
1741
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754
1755
1756
1757
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811
1812
1813
1814
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827
1828
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840
1841
1842
1843
1844
1845
1846
1847
1848
1849
1850
1851
1852
1853
1854
1855
1856
1857
1858
1859
1860
1861
1862
1863
1864
1865
1866
1867
1868
1869
1870
1871
1872
1873
1874
1875
1876
1877
1878
1879
1880
1881
1882
1883
1884
1885
1886
1887
1888
1889
1890
1891
1892
1893
1894
1895
1896
1897
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913
1914
1915
1916
1917
1918
1919
1920
1921
1922
1923
1924
1925
1926
1927
1928
1929
1930
1931
1932
1933
1934
1935
1936
1937
1938
1939
1940
1941
1942
1943
1944
1945
1946
1947
1948
1949
1950
1951
1952
1953
1954
1955
1956
1957
1958
1959
1960
1961
1962
1963
1964
1965
1966
1967
1968
1969
1970
1971
1972
1973
1974
1975
1976
1977
1978
1979
1980
1981
1982
1983
1984
1985
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001
2002
2003
2004
2005
2006
2007
2008
2009
2010
2011
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023
2024
2025
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041
2042
2043
2044
2045
2046
2047
2048
2049
2050
2051
2052
2053
2054
2055
2056
2057
2058
2059
2060
2061
2062
2063
2064
2065
2066
2067
2068
2069
2070
2071
2072
2073
2074
2075
2076
2077
2078
2079
2080
2081
2082
2083
2084
2085
2086
2087
2088
2089
2090
2091
2092
2093
2094
2095
2096
2097
2098
2099
2100
2101
2102
2103
2104
2105
2106
2107
2108
2109
2110
2111
2112
2113
2114
2115
2116
2117
2118
2119
2120
2121
2122
2123
2124
2125
2126
2127
2128
2129
2130
2131
2132
2133
2134
2135
2136
2137
2138
2139
2140
2141
2142
2143
2144
2145
2146
2147
2148
2149
2150
2151
2152
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168
2169
2170
2171
2172
2173
2174
2175
2176
2177
2178
2179
2180
2181
2182
2183
2184
2185
2186
2187
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203
2204
2205
2206
2207
2208
2209
2210
2211
2212
2213
2214
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230
2231
2232
2233
2234
2235
2236
2237
2238
2239
2240
2241
2242
2243
2244
2245
2246
2247
2248
2249
2250
2251
2252
2253
2254
2255
2256
2257
2258
2259
2260
2261
2262
2263
2264
2265
2266
2267
2268
2269
2270
2271
2272
2273
2274
2275
2276
2277
2278
2279
2280
2281
2282
2283
2284
2285
2286
2287
2288
2289
2290
2291
2292
2293
2294
2295
2296
2297
2298
2299
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315
2316
2317
2318
2319
2320
2321
2322
2323
2324
2325
2326
2327
2328
2329
2330
2331
2332
2333
2334
2335
2336
2337
2338
2339
2340
2341
2342
2343
2344
2345
2346
2347
2348
2349
2350
2351
2352
2353
2354
2355
2356
2357
2358
2359
2360
2361
2362
2363
2364
2365
2366
2367
2368
2369
2370
2371
2372
2373
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388
2389
2390
2391
2392
2393
2394
2395
2396
2397
2398
2399
2400
2401
2402
2403
2404
2405
2406
2407
2408
2409
2410
2411
2412
2413
2414
2415
2416
2417
2418
2419
2420
2421
2422
2423
2424
2425
2426
2427
2428
2429
2430
2431
2432
2433
2434
2435
2436
2437
2438
2439
2440
2441
2442
2443
2444
2445
2446
2447
2448
2449
2450
2451
2452
2453
2454
2455
2456
2457
2458
2459
2460
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478
2479
2480
2481
2482
2483
2484
2485
2486
2487
2488
2489
2490
2491
2492
2493
2494
2495
2496
2497
2498
2499
2500
2501
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2512
2513
2514
2515
2516
2517
2518
2519
2520
2521
2522
2523
2524
2525
2526
2527
2528
2529
2530
2531
2532
2533
2534
2535
2536
2537
2538
2539
2540
2541
2542
2543
6%	m`Raekdq]ݔ~#ܖu3][%cU2ߛ
ʞ>Aǟ`	IjJ.Ata֦i(p#2ǫɬUX6S߯33g}[ptN$CpcbgƶK.zz3Qּ}E2R-SCZKaUq^:A$.HSB;'=CP.((*IS\3
Ad46/fIA-oa&7rP;5Bp_EYHjV
epHGT]40e:.w*zTa\/wY-`AFNaD,E	Y	zr61SfA	OS:/ !w
$%o&t-''Z`(7(9*-,\,7-W.n*/01C2V3q.4527 789g:j?;<=g>?@CAAzB^NDZD=ERFE=EEszJ2J!MrNe;PPoQRRaS$TTV~XXZ$[4?\xt\\W] 
_2+`^`!abc+Xdhd$deefQJghh[i+ai3i.iTkYEllEmqmnZnnoooplpp}qSrGWt_t-tf-uOuux}Hy/yvymz4r{+{ ||}rxYfU]jFz;'c_8CISq>\z֔QgII_w!t#H~eF7CGSe
m{J',(	}.CO^EG*rc`8G@ɶϷ	9=8v]V8s:FM
G;
l)Dn	f=J6@L
O5Qs	&J;+Q$}2MxMt;DN$
s
2^'C	gsXXVu.+<'	.	7	G	;II-
 %#>.U
{EK_l~(	2@I'	&|(4NV-
?M\ = R B!
O!=]!!!"##!##$|%v2&t&s''(
!)/)
M)[)g)))))))**'*4*L*f*!y*`***&'+N+{,A\.H012202#3$?3:d3>33334!4-4<4S4#535
K5Y5k5]6f60n6666
66677%79<7v7188M::^:>;R>CB\EiiEEEIFCcGMGG
HHJIJJ
KJXKwKELJaLGLCLF8MIMFMBNBSNCNCNO-P=P
PeQfQVIRYSSTTUWWWWUY1Z&[B[][+z[[[X]]]"]_R_lo_\_N9`T``ka
bXcc|eXeemhfag8hYi\i
j -j\NjjBmnnLn)1p[p;q<q.rr ysuu3Gw {wtwBx<TyoyTzSVzw{m"|6||||.}	}	
)/7g7A(y%_ށ#>b;Wd˅)Ї4C/Bse$nA$Š#b'Go4$Gol!ܓ	$=)Q@o#*r.@Y2j$C޴`c@^ոj-64k
mLG^.6

WD6,P}{SH"Kn%%:\%=1z%
	$.7b?d#;TY_%e'bHLO3	,3.	bl~:


("$*((x305Ldz;BQ]WWe2=HMp#3		
GfYwmc'gvO
o]xJ& 	 Q!$%'(7)LU)))xY*t,G-"c--3--^.
f.q.w../4/+I/,u//////1v1^34404J4
]4h4{444a45+535B5K5]5B63Y6637?7)L7ov7
77
8z89
B;
P;^;v;	;+;<=Z?i?	z?????!?
???@HB	WBvaBLB%Cb;C{CD]DEEUF
GH*H=HLH[]HIIIIJJJ"JJ
JQJDLLO'PDP[P2	Q<RES6TUUU}W1YyZW[(U]I~^bcccccdf
,fm7fnfhi+jjlllll>lNmJn^n9oYopssuuvwwIyz	{{|~~P=ЂbqYzp_`NF?׌tu]i`Ǒ()n^s+{-U٠/en!9ʩaêz%
1I
	

/=ZQʴkp96p4ܻp	hr<q^OS$>	cWmAc4WJm*mRWzYOg{By=4	0}s"NQc`BDB@G\T7	4>uJICnYJG0
	

	|
R3&^j]{^jDE%a<?9A !5!#7$6Q$9$m%0&H'cZ(((i,Q./11213,56	.7N877k689F;HZ<=T?
?CAOB@C94DnDLE)GsGHH@tII[JKcM:NcKOORAP}PQnQ3%RYRRDSw?T7U2UX"V8{VVLKXdXUY7SZ;[[[\]]d^^t_~@``;aaa<c9UdAdde[g.haipvlYmAookkppruqnqWs `shs3twvv{w$xxSyyzM{;~BJQ5hw\ԋόn&|?0pi3xYەyrl7Gơҡ	Τؤ&;YinإN_@	ר98Gı
Ȳֲ?&YԳ.H޷b'1/л
%$9J4p!l-X*+,Vfy}nyZ{@UoqR9
'I@$S $!-E^~nlei\rZUy02\/TN	,

O

[Z>o,!y"]#m&@(~L*.*,.k0rd11p3?45678U899:n;f
=q=M?N@HB[DRlDD-DE$E9ESHEEUEFF'FFXFGZ0G
GGG1G4G!H7H)OHyH/HH)H7	I!AI3cI/I7I3I3J
?J
JJUJjJwJ4JJ'JJ)K1K:>KyK3KK :L:[LLLLL:M?M!^NOQQ%Q -QNQRP!SrTV
VV'VVVVW
W+#W.OW~WWWWWW	GX>QXXX
XXXXXXX
XXYY'Y8YHYNYI[U[[[d[^j[[[]O^e^k^
{^^^4^;^%_9B_a|_4_e`y`2``ib2c)HcrccFccc
cc
cDd>Gddpeye7}fxf	.g8gHgQg'mgg
g	ggghZi$j0jd1l ll0lmDnGn
oqQqb%ssNttbuuv0vwRxeykqydyqBzz4{~{z|3}}u~][^%U\6t>2Aq`I^.tXQOp26E|UaS͗3!U }[-pUCޝp"c{KszV3ѠQW¥Ei2-SCdZaUeq:-hAI$HB;<'x=Pޫ./(^(I\W3j=dWz6Ҳ	Aеa"ɷ7zr%P޺5/e`GB_IEHTm
PbG|D0	]:4S!^a>^L3+2I_-N~RjsfQnI'	q7N 2$%f&Q'U(r!),!e-.K\/^0v2~4\7i8#U:y<>?AzE}HMIJ8KL|MSQWS9TT-VqWIZ"[x]_|atcff?hk/lmgpx
rs
vw5xyz}L~]~t5ZuH.ww~В;O*/[<Bqi/=ƥ:?/3'8.NF:]bD$r̹?HzUý8RhPM}^F~>U*t@wPK\8T@@aeXzuBV')'54]ul (	9o
n~&
 T#$#'F!'h't''x'6''/'A(\)Go*^*+f+?,._,4,,6u.>./)0
1$1<379Cq<?@[BjBsgCDGI]OfOwOkQT1TW.X7Zh:^a:7frhb*kwl1p!7r@Ys$wQyJ}\r
'	Džхˈ)HČ
(!ߑA%C0iz
oj'-e:+̫uy_ON.k$ƴL84N-7-e?
+VC/0
%5k)95o^iw8Fx$/CM$1)NDaF%!;]Gy")5&BLi0-0142OM5AiRX3.4b2/v/<<P1J
'
t=j6=  	-->0$o7/,0)2Z2?01.Q!,-,A*l<- Hj  1u#(%)K{,#--c-AW.A..a/0+0BD0@0)0%0:1S1,253I3!c3:3-55f6j6A666;637/<7Dl787e7P89:J=R>>>:?EKWP|PWxQQWXT_T"U3VPV-Y[Z\aZ\Z[V[[I\]\Y]W]]Z]W^Sh^S^T_Te_k_r&a&abb/cdhg|hii9k!nIn6o?o=q
s1t:t0
uS>u8ux<myyy{{I|}}e~lBXD|`X݃6ÄaYև0
 \"BikƍM2;%aS" 3 t<_oTawmd6ҝI	HS#8(ʡ
֡3ja^3vK Qlw6ժΫ~?jذbC}$HA$Wu57~$o!Jl`{'H(Mv1\SB=\Y7X		.					`|	
	jj	:			#	9		{	a	y	g	?		B"	A#	Q&	'	*	5/	1	2	4	45	c6	-|6	H6	8	9	f#9	-9	j9	V#:	z<	8<	8<	F=	S=	id=	=	y@	B	+D	0&F	WG	+I	;J	%K	<K	EK	MK	L	+L	OL	6+M	bM	gM	mM	|M	!O	O	;O	SO	QP	]P	RVQ	R	;T	U	'Y	!Y	DY	+Z	h;Z	NZ	\	*	]	4]	>M]	]	[`	Ma	.b	4b	Cb	d	!e	,e	3e	'0f	Xf	gf	0yf	"f	f	f	4g	Yg	,.h	[h	eji	i	m	p	t	"u	w	w	|	/|	/|	G|	C}	L	S	)b	G	ԅ	Ph		=	Jތ	6)	`			j	>@		"	8	ȟ	~e			]~	ܦ	d		O*	z	i	Z	B	B			е	ϸ		Ž	v	54	j	-U	9		q	-			}
	h			o	O	B
	M	#			/	8	Y<		3			#		:		)	>	A2	t		A	?				g	G	2\	G	8		40	e	/	1		=~		8		!	t=	)	F	]#			U				2	^R	#	1	;
>C
)

*


%q
)


$
=
/
6
VV
8
?
&	
#



(X





m


(
%

#
8
4


'
?
/
48
m
h
.
#
7
p 
V!
!&
7'
82(
k(
)
,
-
Qy/
y0
E2
Z2
"5
8
;
7<
mI?
A
pI
wK
;K
K
&K

L
M
?P
#GP
kP
IDQ
S
^U
W
TY
?]
N]
W]
.h]
]
.]
_
Nk`
a
;`b
b
Qqe
i
i
"om
m
eo
!p
p
Qs
t
$v
w
y
|
}
^
L:

"0
`S

^
g



]Z


J
8
$
؟
f
d\

o
V.

DD
w

q
~

6
"

M
N

l
0s
 

BG
,


J

'
4
OF

p
+
h


"
	
*

0
y
yx





U



`
;S4	YS
'
_
5bk()tn'3["#
%a
*(o+</~1T35v5z?8p8_+9h<J>?@}S@GAfBD[EuHiM/NNP%QUW6X Z\]^``ab*f]fTgPrim[nq#qrSUtvKxzz6|~"bN,ԁPR߅KuzXOCSo0h	n3JYG\6\_ްn}dlQyNRB\w2EK(MvqqnR*0a[,:;R<.5dTOQUXN'Z<`	|O
F
zlN36j ;<.xf/!s"J
#U%#))g+kD13U6n7k8:29m:";=e='>@BCEEFGG+HJK:{M<Q8S,VM	X/W[M`asc:e/fgiZju9lmpq!r!tuvzk|}!/=my!4ْ=L6l0ԓ.!AO#C3FwNX
XfX*Ûohؠ	/ҡ"
Ze)M@x:tmiTEMhi$QNIL+.&;ZGj+D	WnlYP,D,


n

h}
4
w
!
6
5
{"

(
:"
j	#
vt&
:)
0&*
$W*
"|*
*
n+
?o-
/
<0
2
3
3
4
`G6
7
@:
;=
f=
d?
$@
B
B
lF
H
rL
N
"O
2P
tQ
R
/5U

eV
sW
Z
]
_
`
Ab
c
se
f
h
O~l
m
gn
_p
MYs
v
*x
y
|
#G
k
L.
[{
׍
m

>
R
 E
f

p
Y
,

0

}u



rl
|ߴ
J\
@

R
L
-d

$
ƿ
Sտ
)
U:



4
XK

Z


&
.
1G
4y


6

/-
]
)y
7
!
3
/1
7a
3








4
S
'j

@

`
P
T\

 2
S







!

%


 


P



*

E}
e
M)
qw

+
.*
Y
`
q
2

4

>&
e
n

u

:



3




.
?
P
`
]f







^
&
<
O

_
m

4
;
%
9<
av
4
e

s
=

i
7
)M
Kw
=







D
>
[
q
O
7S
x
/
B4
w

'

5
'
?
X
'



d
L
[
0
C
xJ


s

O
b
P
S

g
e
]
0m
7{.+K:?jB8Rz)3u'Pu5$# 7cDKimCwPP) '	ARtHJz^nFOIvAJs>?ZKLZcy|0pG	<kbq7{p\FZkQnRUHpv=2u4bxdHd=V'9W/C*j28f>cW?:
\0"E!V;\VL_.F'Ky]2
B[dfpI;Ncq"6NS`u:ZU3JU/G+TiOQ~^~vje;IIEqMRC!)Sq'-Vu /khM}1DY%j(UrM^?&Q`TGk.Xo5&"-6Y%^/vn*?H9?!6yoqiSlMvt-X9"0}QnM(|._&B 6SVz<rr&N!-q.MCL4izmJ=Pyab	~@ZQ)%$61YO%(eB\m|8=firX[4QhT7&b~]tp<)^Xt,Im5!O8+iHu&|_dbk,Y{tT3-E~Rmwa>o;lo
jvagcu<w`{8P{5kZc]T
3GaOTe`
M8""[$A*NOE5x	4'B4>t\sXls1A1g#JG<:_/NP,,*O.jr)S:0bj2W];x[lI^}@cA=,Y7ah`+g)
1R0FvEW+IQZ]n?
@H*dse@|\f,o$>DhD82x}
 E(0"T@	=	1%;f&zg<>%sL\hUDgs$39gwdl1Sl0_y6LCCS+7'q`-yUFG^9-yV #<Bha#2Bxm[tWHKY	WnKg9
e,/D] pGwNUN5@wXC~W`n$>{f#@xRs
Ad!YLlzr64J}43$}}VA(
ae(57*zXom:EJxP.+23ifF9
rD_F:!%;L]ekp/[#
w
#{b*|h=K~(|[_o
        GtkSizeRequestMode gtk_widget_get_request_mode(GtkWidget* widget);
      
        GtkToolItem* gtk_tool_button_new(GtkWidget* icon_widget, const gchar*
        label);
      
        _INITIALIZATION(`Gdk::Rectangle&amp;',`GdkRectangle', `$3 =
        Glib::wrap(&amp;($4))')
      
        _INITIALIZATION(`SizeRequestMode&amp;',`GtkSizeRequestMode',`$3 =
        ($1)($4)')
      
        _INITIALIZATION(`SizeRequestMode&amp;',`GtkSizeRequestMode',`$3 =
        (SizeRequestMode)($4)')
      
        _WRAP_CTOR(ToolButton(Widget&amp; icon_widget, const Glib::ustring&amp;
        label{?}), gtk_tool_button_new)
      
        _WRAP_METHOD(bool get_cell_rect(const TreeModel::Path&amp; path, const
        CellRenderer&amp; cell, Gdk::Rectangle&amp; rect{&gt;&gt;}) const,
        gtk_icon_view_get_cell_rect)
      
        _WRAP_METHOD(void get_request_mode(SizeRequestMode&amp; mode{OUT})
        const, gtk_widget_get_request_mode)
      
        _WRAP_METHOD(void set_device_events(Gdk::EventMask events{.}, const
        Glib::RefPtr&lt;const Gdk::Device&gt;&amp; device{.}),
        gtk_widget_set_device_events)
      
        _WRAP_METHOD(void set_device_events(Gdk::EventMask events{events},
        const Glib::RefPtr&lt;const Gdk::Device&gt;&amp; device{device}),
        gtk_widget_set_device_events)
      
        gboolean gtk_icon_view_get_cell_rect(GtkIconView* icon_view,
        GtkTreePath* path, GtkCellRenderer* cell, GdkRectangle* rect);
      
        void gtk_widget_set_device_events(GtkWidget* widget, GdkDevice* device,
        GdkEventMask events);
      
    ...
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
    ...

  $ git clone git://git.gnome.org/mm-common
  $ cp -a mm-common/skeletonmm libsomethingmm

# ./configure
# make
# make install

#include &lt;gtkmm/bin.h&gt;
#include &lt;gtkmm/activatable.h&gt;
_DEFS(gtkmm,gtk)
_PINCLUDE(gtkmm/private/bin_p.h)

namespace Gtk
{

class Button
  : public Bin,
    public Activatable
{
  _CLASS_GTKOBJECT(Button,GtkButton,GTK_BUTTON,Gtk::Bin,GtkBin)
  _IMPLEMENTS_INTERFACE(Activatable)
public:

  _CTOR_DEFAULT
  explicit Button(const Glib::ustring&amp; label, bool mnemonic = false);

  _WRAP_METHOD(void set_label(const Glib::ustring&amp; label), gtk_button_set_label)

  ...

  _WRAP_SIGNAL(void clicked(), "clicked")

  ...

  _WRAP_PROPERTY("label", Glib::ustring)
};

} // namespace Gtk

#include &lt;gtkmm/button.h&gt;

class OverriddenButton : public Gtk::Button
{
protected:
    virtual void on_clicked();
}

void OverriddenButton::on_clicked()
{
    std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;

    // call the base class's version of the method:
    Gtk::Button::on_clicked();
}

#include &lt;gtkmm/button.h&gt;

void on_button_clicked()
{
    std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
}

main()
{
    Gtk::Button button("Hello World");
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
}

#include &lt;gtkmm/button.h&gt;
#include &lt;gtkmm/window.h&gt;
class Foo : public Gtk::Window
{
private:
  Gtk::Button theButton;
  // will be destroyed when the Foo object is destroyed
};

#include &lt;libsomething.h&gt;

int main(int, char**)
{
  something_init();

  std::cout &lt;&lt; get_defs(SOME_TYPE_WIDGET)
            &lt;&lt; get_defs(SOME_TYPE_STUFF);
  return 0;
}

$ ./enum.pl /usr/include/gtk-3.0/gtk/*.h &gt; gtk_enums.defs

$ ./h2def.py /usr/include/gtk-3.0/gtk/*.h &gt; gtk_methods.defs

$ cd gtk/src
$ /usr/lib/glibmm-2.4/proc/gmmproc -I ../../tools/m4 --defs . button . ./../gtkmm

$ cd tools/extra_defs_gen
$ ./generate_extra_defs &gt; gtk_signals.defs

$ for f in $(find libsomethingmm -depth -name '*skeleton*'); do \
    d="${f%/*}"; b="${f##*/}"; mv "$f" "$d/${b//skeleton/libsomething}"; \
  done

&gt; gdb with_signal
(gdb) catch throw
Catchpoint 1 (throw)
(gdb) run
Catchpoint 1 (exception thrown), 0x00714ff0 in __cxa_throw ()
(gdb) backtrace
#0  0x00714ff0 in __cxa_throw () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#1  0x08048bd4 in throwSomething () at with_signal.cc:6
(gdb) continue
Continuing.
(with_signal:2375): glibmm-ERROR **
unhandled exception (type unknown) in signal handler

Program received signal SIGTRAP, Trace/breakpoint trap.

&gt; gdb with_signal
(gdb) run
(with_signal:2703): glibmm-ERROR **:
unhandled exception (type unknown) in signal handler

Program received signal SIGTRAP, Trace/breakpoint trap.
(gdb) backtrace
#2  0x0063c6ab in glibmm_unexpected_exception () at exceptionhandler.cc:77
#3  Glib::exception_handlers_invoke () at exceptionhandler.cc:150
#4  0x0063d370 in glibmm_source_callback (data=0x804d620) at main.cc:212
#13 0x002e1b31 in Gtk::Application::run (this=0x804f300) at application.cc:178
#14 0x08048ccc in main (argc=1, argv=0xbfffecd4) at with_signal.cc:16

&gt; gdb without_signal
(gdb) run
terminate called after throwing an instance of 'char const*'

Program received signal SIGABRT, Aborted.
(gdb) backtrace
#7  0x08048864 in throwSomething () at without_signal.cc:6
#8  0x0804887d in main (argc=1, argv=0xbfffecd4) at without_signal.cc:12

(gdb) catch throw
(gdb) commands
(gdb)   backtrace
(gdb)   continue
(gdb)   end
(gdb) set pagination off
(gdb) run

// _MEMBER_GET_PTR(engine_lang, lang_engine, EngineLang*, PangoEngineLang*)
// It's just a comment. It's difficult to find a real-world example.

// in a class that inherits from Gtk::Window...
Glib::RefPtr&lt;PrintOperation&gt; op = PrintOperation::create();
// ...set up op...
op-&gt;run(Gtk::PRINT_OPERATION_ACTION_PREVIEW, *this);

// in class ExampleWindow's method...
Glib::RefPtr&lt;PrintOperation&gt; op = PrintOperation::create();
// ...set up op...
op-&gt;signal_done().connect(sigc::bind(sigc::mem_fun(*this, &amp;ExampleWindow::on_printoperation_done), op));
// run the op

// with_signal.cc
#include &lt;gtkmm.h&gt;

bool throwSomething()
{
  throw "Something";
  return true;
}

int main(int argc, char** argv)
{
  Glib::signal_timeout().connect(sigc::ptr_fun(throwSomething), 500);
  Glib::RefPtr&lt;Gtk::Application&gt; app =
    Gtk::Application::create(argc, argv, "org.gtkmm.with_signal");
  app-&gt;hold();
  return app-&gt;run();
}

// without_signal.cc
#include &lt;gtkmm.h&gt;

bool throwSomething()
{
  throw "Something";
  return true;
}

int main(int argc, char** argv)
{
  throwSomething();
  Glib::RefPtr&lt;Gtk::Application&gt; app =
    Gtk::Application::create(argc, argv, "org.gtkmm.without_signal");
  return app-&gt;run();
}

//Within a class that inherits from Gtk::Window and keeps m_refPageSetup and m_refSettings as members...
Glib::RefPtr&lt;Gtk::PageSetup&gt; new_page_setup = Gtk::run_page_setup_dialog(*this, m_refPageSetup, m_refSettings);
m_refPageSetup = new_page_setup;

Button::Button(const Glib::ustring&amp; label, bool mnemonic)
:
  _CONSTRUCT("label", label.c_str(), "use_underline", gboolean(mnemonic))
{}

DerivedDialog* pDialog = 0;
builder-&gt;get_widget_derived("DialogBasic", pDialog);

DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr&lt;Gtk::Builder&gt;&amp; builder)
: Gtk::Dialog(cobject)
{
}

DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr&lt;Gtk::Builder&gt;&amp; builder)
: Gtk::Dialog(cobject),
  m_builder(builder),
  m_pButton(0)
{
  //Get the Glade-instantiated Button, and connect a signal handler:
  m_builder-&gt;get_widget("quit_button", m_pButton);
  if(m_pButton)
  {
    m_pButton-&gt;signal_clicked().connect( sigc::mem_fun(*this, &amp;DerivedDialog::on_button_quit) );
  }
}

Glib::RefPtr&lt;Gdk::Pixbuf&gt; pixbuf = Gdk::Pixbuf::create_from_file(filename);

Glib::RefPtr&lt;Gdk::Pixbuf&gt; pixbuf2 = pixbuf;

Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
Gdk::Pixbuf&amp; underlying = *refPixbuf; //Syntax error - will not compile.

Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf2 = refPixbuf;

Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
int width = refPixbuf-&gt;get_width();

Glib::RefPtr&lt;Gtk::Builder&gt; builder = Gtk::Builder::create_from_file("basic.glade");

Glib::RefPtr&lt;Gtk::Builder&gt; builder = Gtk::Builder::create_from_file("basic.glade", "treeview_products");

Glib::RefPtr&lt;Gtk::PrintOperation&gt; op = Gtk::PrintOperation::create();
// ...set up op...
op-&gt;set_export_filename("test.pdf");
Gtk::PrintOperationResult res = op-&gt;run(Gtk::PRINT_OPERATION_ACTION_EXPORT);

Glib::RefPtr&lt;Gtk::TreeModel&gt; refModel = m_TreeView.get_model();
if(refModel)
{
  int cols_count = refModel-&gt;get_n_columns();
  ...
}

Glib::RefPtr&lt;Gtk::TreeStore&gt; refStore =
Glib::RefPtr&lt;Gtk::TreeStore&gt;::cast_dynamic(refModel);
Glib::RefPtr&lt;Gtk::TreeStore&gt; refStore2 =
Glib::RefPtr&lt;Gtk::TreeStore&gt;::cast_static(refModel);

Glib::RefPtr&lt;Gtk::TreeStore&gt; refStore = Gtk::TreeStore::create(columns);
Glib::RefPtr&lt;Gtk::TreeModel&gt; refModel = refStore;

Glib::SignalProxy1&lt;bool, Gtk::DirectionType&gt; signal_focus()

Glib::SignalProxy3&lt;void, const TextBuffer::iterator&amp;, const Glib::ustrin&amp;, int&gt; signal_insert();

Gtk::Button* button = new Gtk::Button("example");
gtk_button_do_something_new(button-&gt;gobj());

Gtk::Button* pButton = new Gtk::Button("Test");

// do something useful with pButton

delete pButton;

Gtk::Dialog* pDialog = 0;
builder-&gt;get_widget("DialogBasic", pDialog);

Gtk::ToolButton* button = Gtk::manage(new Gtk::ToolButton(icon, "Big"));
button-&gt;set_tooltip_text("Big Brush);
group_brushes-&gt;insert(*button);

Gtk::ToolItemGroup* group_brushes =
  Gtk::manage(new Gtk::ToolItemGroup("Brushes"));
m_ToolPalette.add(*group_brushes);

Gtk::Widget* CustomPrintOperation::on_create_custom_widget()
{
  set_custom_tab_label("My custom tab");

  Gtk::Box* hbox = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 8);
  hbox-&gt;set_border_width(6);

  Gtk::Label* label = Gtk::manage(new Gtk::Label("Enter some text: "));
  hbox-&gt;pack_start(*label, false, false);
  label-&gt;show();

  hbox-&gt;pack_start(m_Entry, false, false);
  m_Entry.show();

  return hbox;
}

void CustomPrintOperation::on_custom_widget_apply(Gtk::Widget* /* widget */)
{
  Glib::ustring user_input = m_Entry.get_text();
  //...
}

GtkButton* cbutton = get_a_button();
Gtk::Button* button = Glib::wrap(cbutton);

GtkWidget* example_widget_new(int something, const char* thing)
{
        ExampleWidget* widget;
        widget = g_object_new (EXAMPLE_TYPE_WIDGET, NULL);
        example_widget_construct(widget, "something", something, "thing", thing);
}

void example_widget_construct(ExampleWidget* widget, int something, const char* thing)
{
        //Do stuff that uses private API:
        widget-&gt;priv-&gt;thing = thing;
        do_something(something);
}

GtkWidget* example_widget_new(int something, const char* thing)
{
        return g_object_new (EXAMPLE_TYPE_WIDGET, "something", something, "thing", thing, NULL);
}

MyContainer::MyContainer()
{
  Gtk::Button* pButton = Gtk::manage(new Gtk::Button("Test"));
  add(*pButton); //add *pButton to MyContainer
}

_CLASS_BOXEDTYPE(RGBA, GdkRGBA, NONE, gdk_rgba_copy, gdk_rgba_free)

_CLASS_BOXEDTYPE_STATIC(Rectangle, GdkRectangle)

_CLASS_GENERIC(AttrIter, PangoAttrIterator)

_CLASS_GOBJECT(AccelGroup, GtkAccelGroup, GTK_ACCEL_GROUP, Glib::Object, GObject)

_CLASS_GTKOBJECT(Button, GtkButton, GTK_BUTTON, Gtk::Bin, GtkBin)

_CLASS_INTERFACE(CellEditable, GtkCellEditable, GTK_CELL_EDITABLE, GtkCellEditableIface)

_CLASS_INTERFACE(LoadableIcon, GLoadableIcon, G_LOADABLE_ICON, GLoadableIconIface, Icon, GIcon)

_CLASS_OPAQUE_COPYABLE(Checksum, GChecksum, NONE, g_checksum_copy, g_checksum_free)

_CLASS_OPAQUE_REFCOUNTED(Coverage, PangoCoverage, pango_coverage_new, pango_coverage_ref, pango_coverage_unref)

_CONVERSION(`GtkTreeView*',`TreeView*',`Glib::wrap($3)')

_CONVERSION(`PrintSettings&amp;',`GtkPrintSettings*',__FR2P)
_CONVERSION(`const PrintSettings&amp;',`GtkPrintSettings*',__FCR2P)
_CONVERSION(`const Glib::RefPtr&lt;Printer&gt;&amp;',`GtkPrinter*',__CONVERT_REFPTR_TO_P($3))

_IGNORE(gtk_button_box_set_spacing, gtk_button_box_get_spacing)

_IMPLEMENTS_INTERFACE(Activatable)

_INITIALIZATION(`Gtk::Widget&amp;',`GtkWidget*',`$3 = Glib::wrap($4)')

_MEMBER_GET_GOBJECT(layout, layout, Pango::Layout, PangoLayout*)

_WRAP_ENUM(IconLookupFlags, GtkIconLookupFlags, NO_GTYPE)

_WRAP_ENUM(WindowType, GtkWindowType)

_WRAP_GERROR(PixbufError, GdkPixbufError, GDK_PIXBUF_ERROR)

_WRAP_METHOD(void set_text(const Glib::ustring&amp; text), gtk_entry_set_text)

_WRAP_METHOD_DOCS_ONLY(gtk_container_remove)

_WRAP_PROPERTY("label", Glib::ustring)

_WRAP_SIGNAL(void clicked(),"clicked")

_WRAP_VFUNC(SizeRequestMode get_request_mode() const, get_request_mode)

bool MyCallback() { std::cout &lt;&lt; "Hello World!\n" &lt;&lt; std::endl; return true; }

bool idleFunc();

bool input_callback(Glib::IOCondition condition);

bool on_button_press(GdkEventButton* event);
Gtk::Button button("label");
button.signal_button_press_event().connect( sigc::ptr_fun(&amp;on_button_press) );

bool on_key_press_or_release_event(GdkEventKey* event)
{
  if (event-&gt;type == GDK_KEY_PRESS &amp;&amp;
    event-&gt;keyval == GDK_KEY_1 &amp;&amp;
    (event-&gt;state &amp; (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
  {
    handle_alt_1_press(); // GDK_MOD1_MASK is normally the Alt key
    return true;
  }
  return false;
}

Gtk::Entry m_entry; // in a class definition

// in the class constructor
m_entry.signal_key_press_event().connect( sigc::ptr_fun(&amp;on_key_press_or_release_event) );
m_entry.signal_key_release_event().connect( sigc::ptr_fun(&amp;on_key_press_or_release_event) );
m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);

button.signal_button_press_event().connect( sigc::ptr_fun(&amp;on_mywindow_button_press), false );

class Server
{
public:
  //signal accessor:
  typedef sigc::signal&lt;void, bool, int&gt; type_signal_something;
  type_signal_something signal_something();

protected:
  type_signal_something m_signal_something;
};

Server::type_signal_something Server::signal_something()
{
  return m_signal_something;
}

class TextMark : public Glib::Object
{
  _CLASS_GOBJECT(TextMark, GtkTextMark, GTK_TEXT_MARK, Glib::Object, GObject)

protected:
  _WRAP_CTOR(TextMark(const Glib::ustring&amp; name, bool left_gravity = true), gtk_text_mark_new)

public:
  _WRAP_CREATE(const Glib::ustring&amp; name, bool left_gravity = true)

example-widget.h:56: error: using typedef-name 'ExampleWidget' after 'struct'
../../libexample/libexamplemm/example-widget.h:34: error: 'ExampleWidget' has a previous declaration here
make[4]: *** [example-widget.lo] Error 1

example-widget.h:60: error: '_ExampleWidget ExampleWidget' redeclared as different kind of symbol
../../libexample/libexamplemm/example-widget.h:34: error: previous declaration of 'typedef struct _ExampleWidget ExampleWidget'

int width = 0;
if(pixbuf)
{
  width = pixbuf-&gt;get_width();
}

m_button1.signal_clicked().connect( sigc::bind&lt;Glib::ustring&gt;( sigc::mem_fun(*this, &amp;HelloWorld::on_button_clicked), "button 1") );

my_connection.disconnect();

server.signal_something().connect(
  sigc::mem_fun(client, &amp;Client::on_server_something) );

sigc::connection  Glib::SignalIdle::connect(const sigc::slot&lt;bool&gt;&amp; slot,
                                    int priority = Glib::PRIORITY_DEFAULT_IDLE);

sigc::connection Glib::SignalIO::connect(const sigc::slot&lt;bool,Glib::IOCondition&gt;&amp; slot,
                                 int fd, Glib::IOCondition condition,
                                 int priority = Glib::PRIORITY_DEFAULT);

sigc::connection Glib::SignalTimeout::connect(const sigc::slot&lt;bool&gt;&amp; slot,
                                      unsigned int interval, int priority = Glib::PRIORITY_DEFAULT);

sigc::signal&lt;void, bool, int&gt; signal_something;

sigc::signal&lt;void,int&gt;::iterator signal&lt;void,int&gt;::connect( const sigc::slot&lt;void,int&gt;&amp; );

std::list&lt; Glib::RefPtr&lt;Gdk::Pixbuf&gt; &gt; listPixbufs;
Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
listPixbufs.push_back(refPixbuf);

typedef struct _ExampleWidget ExampleWidget;

struct _ExampleWidget
{
  ...
};

virtual void on_button_clicked(Glib::ustring data);

void ExampleWindow::on_printoperation_done(Gtk::PrintOperationResult result, const Glib::RefPtr&lt;PrintOperation&gt;&amp; op)
{
  if (result == Gtk::PRINT_OPERATION_RESULT_ERROR)
    //notify user
  else if (result == Gtk::PRINT_OPERATION_RESULT_APPLY)
    //Update PrintSettings with the ones used in this PrintOperation

  if (! op-&gt;is_finished())
    op-&gt;signal_status_changed().connect(sigc::bind(sigc::mem_fun(*this, &amp;ExampleWindow::on_printoperation_status_changed), op));
}

void ExampleWindow::on_printoperation_status_changed(const Glib::RefPtr&lt;PrintFormOperation&gt;&amp; op)
{
  if (op-&gt;is_finished())
    //the print job is finished
  else
    //get the status with get_status() or get_status_string()

  //update UI
}

void init()
{
  Gtk::Main::init_gtkmm_internals(); //Sets up the g type system and the Glib::wrap() table.
  wrap_init(); //Tells the Glib::wrap() table about the libsomethingmm classes.
}

void on_button_clicked();

class some_class
{
    void on_button_clicked();
};

some_class some_object;

main()
{
    Gtk::Button button;
    button.signal_clicked().connect( sigc::ptr_fun(&amp;on_button_clicked) );
    button.signal_clicked().connect( sigc::mem_fun(some_object, &amp;some_class::on_button_clicked) );
}

void on_insert(const TextBuffer::iterator&amp; pos, const Glib::ustring&amp; text, int bytes)

{
  Gtk::Button aButton;
  aButton.show();
  ...
  app-&gt;run();
}
"Hidden" Columns# keep this file sorted alphabetically, one language code per line
de
ja#include &lt;gtkmm.h&gt;#m4 _CONVERSION(`GSList*',`std::vector&lt;Widget*&gt;',`Glib::SListHandler&lt;Widget*&gt;::slist_to_vector($3, Glib::OWNERSHIP_SHALLOW)')$ ./plug &amp;$ ./socket(An aside: <application>GTK+</application> calls this scheme "signalling"; the sharp-eyed reader with GUI toolkit experience will note that this same design is often seen under the name of "broadcaster-listener" (e.g., in Metrowerks' PowerPlant framework for the Macintosh). It works in much the same way: one sets up <literal>broadcasters</literal>, and then connects <literal>listeners</literal> to them; the broadcaster keeps a list of the objects listening to it, and when someone gives the broadcaster a message, it calls all of its objects in its list with the message. In <application>gtkmm</application>, signal objects play the role of broadcasters, and slots play the role of listeners - sort of. More on this later.)(In addition, you'd have the files <literal>ja.po</literal> and <literal>de.po</literal> in your <literal>po</literal> directory which contain the German and Japanese translations, respectively.)./docextract_to_xml.py -s ~/checkout/gnome/gtk+/gtk/ &gt; gtk_docs.xml
// creates its own adjustments
Gtk::TextView textview;
// uses the newly-created adjustment for the scrollbar as well
Gtk::Scrollbar vscrollbar (textview.get_vadjustment(), Gtk::ORIENTATION_VERTICAL);// note to translators: don't translate the "[noun]" part - it is
// just here to distinguish the string from another "jumps" string
text = strip(gettext("jumps[noun]"), "[noun]");//compiler error - no conversion from ustring to int.
int number = row[m_Columns.m_col_text];2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010<application>Gtk::Builder</application> checks for a null pointer, and checks that the widget is of the expected type, and will show warnings on the command line about these.<application>glibmm</application> provides the normal set of thread launching functions, mutexes, condition variables and scoped locking classes required for writing multi-threaded programs using C++.<application>gtkmm</application> 3 added some new classes:<application>gtkmm</application> 3 also made several small changes to the API, which you will probably encounter when porting code that used <application>gtkmm</application>-2.4. Here is a short list:<application>gtkmm</application> 3's library is called <literal>libgtkmm-3.0</literal> rather than <literal>libgtkmm-2.4</literal> and installs its headers in a similarly-versioned directory, so your pkg-config check should ask for <literal>gtkmm-3.0</literal> rather than <literal>gtkmm-2.4</literal>.<application>gtkmm</application> allows the programmer to control the lifetime (that is, the construction and destruction) of any widget in the same manner as any other C++ object. This flexibility allows you to use <literal>new</literal> and <literal>delete</literal> to create and destroy objects dynamically or to use regular class members (that are destroyed automatically when the class is destroyed) or to use local instances (that are destroyed when the instance goes out of scope). This flexibility is not present in some C++ GUI toolkits, which restrict the programmer to only a subset of C++'s memory management features.<application>gtkmm</application> allows you to write code using normal C++ techniques such as encapsulation, derivation, and polymorphism. As a C++ programmer you probably already realise that this leads to clearer and better organized code.<application>gtkmm</application> and Win32<application>gtkmm</application> applications can easily support multiple languages, including non-European languages such as Chinese and right-to-left languages such as Arabic. An appropriately-written and translated <application>gtkmm</application> application will use the appropriate language at runtime based on the user's environment.<application>gtkmm</application> applications consist of windows containing widgets, such as buttons and text boxes. In some other systems, widgets are called "controls". For each widget in your application's windows, there is a C++ object in your application's code. So you just need to call a method of the widget's class to affect the visible widget.<application>gtkmm</application> arranges widgets hierarchically, using <emphasis>containers</emphasis>. A Container widget contains other widgets. Most <application>gtkmm</application> widgets are containers. Windows, Notebook tabs, and Buttons are all container widgets. There are two flavours of containers: single-child containers, which are all descendants of <classname>Gtk::Bin</classname>, and multiple-child containers, which are descendants of <classname>Gtk::Container</classname>. Most widgets in <application>gtkmm</application> are descendants of <classname>Gtk::Bin</classname>, including <classname>Gtk::Window</classname>.<application>gtkmm</application> classes are designed with overriding in mind; they contain virtual member methods specifically intended to be overridden.<application>gtkmm</application> compared to Qt<application>gtkmm</application> currently works with the <ulink url="http://mingw.org/">MingW/GCC3.4 compiler</ulink> and Microsoft Visual C++ 2005 or later (including the freely available express editions) on the Windows platform. There is an <ulink url="ftp://ftp.gnome.org/pub/GNOME/binaries/win32/gtkmm"> installer</ulink> available for gtkmm on Microsoft Windows. Refer to <ulink url="http://live.gnome.org/gtkmm/MSWindows/"> http://live.gnome.org/gtkmm/MSWindows</ulink> for instructions how to use it.<application>gtkmm</application> developers tend to prefer <application>gtkmm</application> to Qt because <application>gtkmm</application> does things in a more C++ way. Qt originates from a time when C++ and the standard library were not standardised or well supported by compilers. It therefore duplicates a lot of stuff that is now in the standard library, such as containers and type information. Most significantly, Trolltech modified the C++ language to provide signals, so that Qt classes cannot be used easily with non-Qt classes. <application>gtkmm</application> was able to use standard C++ to provide signals without changing the C++ language. See the <ulink url="https://wiki.gnome.org/gtkmm/FAQ">FAQ</ulink> for more detailed differences.<application>gtkmm</application> has various widgets that can be visually adjusted using the mouse or the keyboard, such as the <classname>Range</classname> widgets (described in the <link linkend="chapter-range-widgets">Range Widgets</link> section). There are also a few widgets that display some adjustable part of a larger area, such as the <classname>Viewport</classname> widget. These widgets have <classname>Gtk::Adjustment</classname> objects that express this common part of their API.<application>gtkmm</application> involves less code compared to GTK+, which uses prefixed function names and lots of cast macros.<application>gtkmm</application> is a C++ wrapper for <ulink url="http://www.gtk.org/">GTK+</ulink>, a library used to create graphical user interfaces. It is licensed using the LGPL license, so you can develop open software, free software, or even commercial non-free software using <application>gtkmm</application> without purchasing licenses.<application>gtkmm</application> is a wrapper<application>gtkmm</application> is more type-safe, so the compiler can detect errors that would only be detected at run time when using C. This use of specific types also makes the API clearer because you can see what types should be used just by looking at a method's declaration.<application>gtkmm</application> is not a native C++ toolkit, but a C++ wrapper of a C toolkit. This separation of interface and implementation has advantages. The <application>gtkmm</application> developers spend most of their time talking about how <application>gtkmm</application> can present the clearest API, without awkward compromises due to obscure technical details. We contribute a little to the underlying GTK+ code base, but so do the C coders, and the Perl coders and the Python coders, etc. Therefore GTK+ benefits from a broader user base than language-specific toolkits - there are more implementers, more developers, more testers, and more users.<application>gtkmm</application> makes it very easy to derive new widgets by inheriting from an existing widget class, either by deriving from a container and adding child widgets, or by deriving from a single-item widget, and changing its behaviour. But you might occasionally find that no suitable starting point already exists. In this case, you can implement a widget from scratch.<application>gtkmm</application> provides an easy way to manage recently used documents. The classes involved in implementing this functionality are <classname>RecentManager</classname>, <classname>RecentChooserDialog</classname>, <classname>RecentChooserMenu</classname>, <classname>RecentChooserWidget</classname>, <classname>RecentAction</classname>, and <classname>RecentFilter</classname>.<application>gtkmm</application> provides four basic types of buttons:<application>gtkmm</application> provides the <function>manage()</function> function and <methodname>add()</methodname> methods to create and destroy widgets. Every widget except a top-level window must be added or packed into a container in order to be displayed. The <function>manage()</function> function marks a widget so that when the widget is added to a container, the container becomes responsible for deleting the widget.<application>gtkmm</application> signal handlers are strongly-typed, whereas <application>GTK+</application> C code allows you to connect a callback with the wrong number and type of arguments, leading to a segfault at runtime. And, unlike <application>Qt</application>, <application>gtkmm</application> achieves this without modifying the C++ language.<application>gtkmm</application> uses the <command>gmmproc</command> tool to generate most of its source code, using .defs files that define the APIs of <classname>GObject</classname>-based libraries. So it's quite easy to create additional gtkmm-style wrappers of other glib/GObject-based libraries.<application>gtkmm</application> uses the libsigc++ library to implement signals. Here is an example line of code that connects a Gtk::Button's "clicked" signal with a signal handler called "on_button_clicked": <placeholder-1/><application>gtkmm</application> uses the packing system to solve these problems. Rather than specifying the position and size of each widget in the window, you can arrange your widgets in rows, columns, and/or grids. <application>gtkmm</application> can size your window automatically, based on the sizes of the widgets it contains. And the sizes of the widgets are, in turn, determined by the amount of text they contain, or the minimum and maximum sizes that you specify, and/or how you have requested that the available space should be shared between sets of widgets. You can perfect your layout by specifying padding distance and centering values for each of your widgets. <application>gtkmm</application> then uses all this information to resize and reposition everything sensibly and smoothly when the user manipulates the window.<application>gtkmm</application> was originally named gtk-- because GTK+ already has a + in the name. However, as -- is not easily indexed by search engines the package generally went by the name <application>gtkmm</application>, and that's what we stuck with.<application>gtkmm</application> widget classes have signal accessor methods, such as <methodname>Gtk::Button::signal_clicked()</methodname>, which allow you to connect your signal handler. Thanks to the flexibility of <application>libsigc++</application>, the callback library used by <application>gtkmm</application>, the signal handler can be almost any kind of function, but you will probably want to use a class method. Among <application>GTK+</application> C coders, these signal handlers are often named callbacks.<application>gtkmm</application>, like most GUI toolkits, is <emphasis>event-driven</emphasis>. When an event occurs, such as the press of a mouse button, the appropriate signal will be <emphasis>emitted</emphasis> by the Widget that was pressed. Each Widget has a different set of signals that it can emit. To make a button click result in an action, we set up a <emphasis>signal handler</emphasis> to catch the button's "clicked" signal.<application>gtkmm</application>-3.0 is a new version of the <application>gtkmm</application> API that installs in parallel with the older <application>gtkmm</application>-2.4 API. The last version of the <application>gtkmm</application>-2.4 API was <application>gtkmm</application> 2.24. <application>gtkmm</application> 3 has no major fundamental differences to <application>gtkmm</application> 2 but does make several small changes that were not possible while maintaining binary compatibility. If you never used the <application>gtkmm</application>-2.4 API then you can safely ignore this chapter.<application>intltool</application> / <application>xgettext</application> script extracts the strings and puts them in a <filename>mypackage.pot</filename> file. The translators of your application create their translations by first copying this <filename>.pot</filename> file to a <filename>localename.po</filename> file. A locale identifies a language and an encoding for that language, including date and numerical formats. Later, when the text in your source code has changed, the <literal>msmerge</literal> script is used to update the <filename>localename.po</filename> files from the regenerated <filename>.pot</filename> file.<classname>ButtonBox</classname>es help to make applications appear consistent because they use standard settings, such as inter-button spacing and packing.<classname>Gdk::Drawable</classname> was removed, with its methods moving into <classname>Gdk::Window</classname>.<classname>Gdk::Pixmap</classname> and <classname>Gdk::Bitmap</classname> were removed in favour of <classname>Gdk::Pixbuf</classname>.<classname>Gdk::RGBA</classname> replaces <classname>Color</classname>, adding an alpha component for opacity. <classname>Colormap</classname> was removed, along with its awkward use to allocate colors.<classname>Glib::ListHandle&lt;Gtk::Widget*&gt;</classname>: Use <classname>std::vector&lt;Gtk::Widget*&gt;</classname>, <classname>std::list&lt;Gtk::Widget*&gt;</classname>, etc.<classname>Glib::RefPtr</classname> is a smartpointer. Specifically, it is a reference-counting smartpointer. You might be familiar with <classname>std::auto_ptr&lt;&gt;</classname>, <classname>std::unique_ptr&lt;&gt;</classname> and <classname>std::shared_ptr&lt;&gt;</classname>, which are also smartpointers. <classname>Glib::RefPtr&lt;&gt;</classname> is similar to <classname>std::shared_ptr&lt;&gt;</classname>, which is also reference-counting. <classname>Glib::RefPtr&lt;&gt;</classname> was introduced long before there was a reference-counting smartpointer in the C++ Standard Library.<classname>Glib::SListHandle&lt;Gtk::Widget*&gt;</classname>: Use <classname>std::vector&lt;Gtk::Widget*&gt;</classname>, <classname>std::list&lt;Gtk::Widget*&gt;</classname>, etc.<classname>Glib::StringArrayHandle</classname> or <classname>Glib::ArrayHandle&lt;Glib::ustring&gt;</classname>: Use <classname>std::vector&lt;Glib::ustring&gt;</classname>, <classname>std::list&lt;Glib::ustring&gt;</classname>, <type>const char*[]</type>, etc.<classname>Gtk::Adjustment</classname> and <classname>IconSet</classname> and <classname>Gdk::Cursor</classname> are now used via <classname>Glib::RefPtr</classname>.<classname>Gtk::AppChooser</classname>, <classname>Gtk::AppChooserButton</classname>, <classname>Gtk::AppChooserDialog</classname> allow the user to select an installed application to open a particular type of content.<classname>Gtk::Box</classname> arranges its child widgets vertically or horizontally. Use <methodname>pack_start()</methodname> and <methodname>pack_end()</methodname> to insert child widgets.<classname>Gtk::Box</classname>, <classname>Gtk::ButtonBox</classname>, <classname>Gtk::IconView</classname>, <classname>Gtk::Paned</classname>, <classname>Gtk::ProgressBar</classname>, <classname>Gtk::ScaleButton</classname>, <classname>Gtk::Scrollbar</classname> and <classname>Gtk::Separator</classname> now derive from <classname>Gtk::Orientable</classname>, allowing their orientation (vertical or horizontal) to be specified without requiring the use of a derived class such as <classname>Gtk::HBox</classname>.<classname>Gtk::Builder</classname> must be used via a <classname>Glib::RefPtr</classname>. Like all such classes, you need to use a <methodname>create()</methodname> method to instantiate it. For instance, <placeholder-1/> This will instantiate the windows defined in the .glade file, though they will not be shown immediately unless you have specified that via the <guilabel>Properties</guilabel> window in <application>Glade</application>.<classname>Gtk::Button</classname> is also a container so you could put any other widget, such as a <classname>Gtk::Image</classname> into it.<classname>Gtk::CellLayout</classname>, used by <classname>Gtk::IconView</classname>, <classname>Gtk::TreeView::Column</classname> and <classname>Gtk::ComboBox</classname>, now has a <classname>Gtk::CellArea</classname> which can be used to specify more details of how the <classname>CellRenderer</classname>s are arranged and aligned.<classname>Gtk::CheckButton</classname> inherits from <classname>Gtk::ToggleButton</classname>. The only real difference between the two is <classname>Gtk::CheckButton</classname>'s appearance. You can check, set, and toggle a checkbox using the same member methods as for <classname>Gtk::ToggleButton</classname>.<classname>Gtk::Grid</classname> arranges its child widgets in rows and columns. Use <methodname>attach()</methodname>, <methodname>attach_next_to()</methodname> and <methodname>add()</methodname> to insert child widgets.<classname>Gtk::Grid</classname> is a new container widget that will eventually replace <classname>Gtk::Box</classname> and <classname>Gtk::Table</classname>. It arranges its children according to properties of those children rather than its own layout details.<classname>Gtk::IconView</classname>, <classname>Gtk::TextView</classname>, <classname>Gtk::TreeView</classname> and other widgets derive from Scrollable instead of having their own methods such as <methodname>get_vadjustment()</methodname> and instead of having their own set_scroll_adjustments signal.<classname>Gtk::Scale</classname> and <classname>Gtk::Scrollbar</classname> both inherit from <classname>Gtk::Range</classname> and share much functionality. They contain a "trough" and a "slider" (sometimes called a "thumbwheel" in other GUI environments). Dragging the slider with the pointer moves it within the trough, while clicking in the trough advances the slider towards the location of the click, either completely, or by a designated amount, depending on which mouse button is used. This should be familiar scrollbar behaviour.<classname>Gtk::Scale</classname> widgets (or "sliders") allow the user to visually select and manipulate a value within a specific range. You might use one, for instance, to adjust the magnification level on a zoomed preview of a picture, or to control the brightness of a colour, or to specify the number of minutes of inactivity before a screensaver takes over the screen.<classname>Gtk::Style</classname> and <classname>Gtk::Rc</classname> were removed, replaced by <classname>Gtk::StyleContext</classname>, and <classname>Gtk::StyleProvider</classname>s, such as <classname>Gtk::CssProvider</classname>.<classname>Gtk::Switch</classname> displays On/Off states more explictly than <classname>Gtk::CheckBox</classname>. It may be useful, for instance, when allowing users to activate hardware.<classname>Gtk::Table</classname> allows us to place widgets in a grid, similar to <classname>Gtk::Grid</classname>.<classname>Gtk::Table</classname> is deprecated from <application>gtkmm</application> version 3.4 and should not be used in newly-written code. Use <classname>Gtk::Grid</classname> instead.<classname>Gtk::TargetEntry</classname> objects contain this information: <placeholder-1/><classname>Gtk::TextBuffer</classname> is a model containing the data for the <classname>Gtk::TextView</classname>, like the <classname>Gtk::TreeModel</classname> used by <classname>Gtk::TreeView</classname>. This allows two or more <classname>Gtk::TextView</classname>s to share the same <classname>TextBuffer</classname>, and allows those TextBuffers to be displayed slightly differently. Or you could maintain several <classname>Gtk::TextBuffer</classname>s and choose to display each one at different times in the same <classname>Gtk::TextView</classname> widget.<classname>Gtk::TextView</classname> has various <methodname>scroll_to_*()</methodname> methods. These allow you to ensure that a particular part of the text buffer is visible. For instance, your application's Find feature might use <methodname>Gtk::TextView::scroll_to_iter()</methodname> to show the found text.<classname>Gtk::ToggleButton</classname> is most useful as a base class for the <classname>Gtk::CheckButton</classname> and <classname>Gtk::RadioButton</classname> classes.<classname>Gtk::ToolItem</classname>s can then be added to the group. For instance, like so:<classname>Gtk::TreeModel</classname> provides a C++ Standard Library-style container of its children, via the <methodname>children()</methodname> method. You can use the familiar <methodname>begin()</methodname> and <methodname>end()</methodname> methods iterator incrementing, like so:<classname>Gtk::TreeStore</classname> models can have child items. Add them with the <methodname>append()</methodname>, <methodname>prepend()</methodname>, or <methodname>insert()</methodname> methods, like so:<classname>Gtk::TreeView</classname> already implements simple drag-and-drop when used with the <classname>Gtk::ListStore</classname> or <classname>Gtk::TreeStore</classname> models. If necessary, it also allows you to implement more complex behaviour when items are dragged and dropped, using the normal <link linkend="chapter-draganddrop">Drag and Drop</link> API.<classname>Gtk::Widget</classname> has several methods and signals which are prefixed with "drag_". These are used for Drag and Drop.<classname>Menus</classname> are normally just added to a window, but they can also be displayed temporarily as the result of a mouse button click. For instance, a context menu might be displayed when the user clicks their right mouse button.<classname>MessageDialog</classname> is a convenience class, used to create simple, standard message dialogs, with a message, an icon, and buttons for user response. You can specify the type of message and the text in the constructor, as well as specifying standard buttons via the <literal>Gtk::ButtonsType</literal> enum.<classname>RadioButtons</classname> are "off" when created; this means that when you first make a group of them, they will all be off. Don't forget to turn one of them on using <methodname>set_active()</methodname>:<classname>Range</classname> widgets typically connect a handler to this signal, which changes their appearance to reflect the change - for example, the size of the slider in a scrollbar will grow or shrink in inverse proportion to the difference between the <parameter>lower</parameter> and <parameter>upper</parameter> values of its <classname>Adjustment</classname>.<classname>RecentChooser</classname> is an interface that can be implemented by widgets displaying the list of recently used files. <application>gtkmm</application> provides four built-in implementations for choosing recent files: <classname>RecentChooserWidget</classname>, <classname>RecentChooserDialog</classname>, <classname>RecentChooserMenu</classname>, and <classname>RecentAction</classname>.<classname>RecentChooserMenu</classname> and <classname>RecentAction</classname> allow you to list recently used files as a menu.<classname>RecentChooserWidget</classname> is a simple widget for displaying a list of recently used files. <classname>RecentChooserWidget</classname> is the basic building block for <classname>RecentChooserDialog</classname>, but you can embed it into your user interface if you want to.<classname>RecentManager</classname> acts as a database of recently used files. You use this class to register new files, remove files from the list, or look up recently used files. There is one list of recently used files per user.<classname>RecentManager</classname> is the model of a model-view pattern, where the view is a class that implements the <classname>RecentChooser</classname> interface.<classname>Scale</classname> widgets can display their current value as a number next to the trough. By default they show the value, but you can change this with the <methodname>set_draw_value()</methodname> method.<classname>ScrolledWindow</classname> widgets create a scrollable area. You can insert any type of widget into a <classname>ScrolledWindow</classname> window, and it will be accessible regardless of its size by using the scrollbars. Note that <classname>ScrolledWindow</classname> is not a <classname>Gtk::Window</classname> despite the slightly misleading name.<classname>SpinButton</classname>s use an <link linkend="chapter-adjustment">Adjustment</link> object to hold information about the range of values. These Adjustment attributes are used by the Spin Button like so: <placeholder-1/><classname>TextBuffer</classname> iterators are generally invalidated when the text changes, but you can use a <classname>Gtk::TextBuffer::Mark</classname> to remember a position in these situations. For instance,<classname>TextView</classname> has various methods which allow you to change the presentation of the buffer for this particular view. Some of these may be overridden by the <classname>Gtk::TextTag</classname>s in the buffer, if they specify the same things. For instance, <methodname>set_left_margin()</methodname>, <methodname>set_right_margin()</methodname>, <methodname>set_indent()</methodname>, etc.<classname>ToggleButton</classname>s are like normal <classname>Button</classname>s, but when clicked they remain activated, or pressed, until clicked again.<classname>ToolItemGroup</classname>s should be added to the tool palette via the base class's <function>Gtk::Container::add()</function> method, for instance like so:<classname>Widget</classname>s can be identified as sources or destinations using these <classname>Gtk::Widget</classname> methods:<command>gmmproc</command> allows processing the parameters in a method signature for the macros that process method signatures (like <function>_WRAP_METHOD()</function>, <function>_WRAP_CTOR()</function> and <function>_WRAP_CREATE()</function>) in a variety of ways:<command>gmmproc</command> will warn you on stdout about functions and signals that you have forgotten to wrap, helping to ensure that you are wrapping the complete API. But if you don't want to wrap some functions or signals, or if you chose to hand-code some methods then you can use the _IGNORE() or _IGNORE_SIGNAL() macro to make <command>gmmproc</command> stop complaining.<filename>libsomething</filename>: Contains the main include file and the pkg-config .pc file.<filename>libsomethingmm</filename>: Contains generated and hand-written .h and .cc files.<filename>libsomethingmm</filename>: The top-level directory.<filename>private</filename>: Contains generated <filename>*_p.h</filename> files.<filename>src</filename>: Contains .hg and .ccg source files.<function>_WRAP_METHOD()</function> also supports setting C++ output parameters from C output parameters if the C function being wrapped has any. Suppose, for example, that we want to wrap the following C function that returns a value in its C output parameter <parameter>rect</parameter>: <placeholder-1/> To have <command>gmmproc</command> place the value returned in the C++ <parameter>rect</parameter> output parameter, something like the following <function>_WRAP_METHOD()</function> directive could be used: <placeholder-2/> The <literal>{&gt;&gt;}</literal> following the <parameter>rect</parameter> parameter name indicates that the C++ output parameter should be set from the value returned in the C parameter from the C function. <command>gmmproc</command> will generate a declaration of a temporary variable in which to store the value of the C output parameter and a statement that sets the C++ output parameter from the temporary variable. In this case it may be necessary to have an <function>_INITIALIZATION()</function> describing how to set a <classname>Gdk::Rectangle&amp;</classname> from a <classname>GdkRectangle*</classname> such as the following: <placeholder-3/><function>_WRAP_METHOD()</function>, <function>_WRAP_SIGNAL()</function>, and <function>_WRAP_PROPERTY()</function><function>sigc::bind()</function> is not commonly used, but you might find it helpful sometimes. If you are familiar with <application>GTK+</application> programming then you have probably noticed that this is similar to the extra <literal>gpointer data</literal> arguments which all GTK+ callbacks have. This is generally overused in <application>GTK+</application> to pass information that should be stored as member data in a derived widget, but widget derivation is very difficult in C. We have far less need of this hack in <application>gtkmm</application>.<function>sigc::ptr_fun()</function> generates a <classname>sigc::slot</classname>. A slot is an object which looks and feels like a function, but is actually an object. These are also known as function objects, or functors. <function>sigc::ptr_fun()</function> generates a slot for a standalone function or static method. <function>sigc::mem_fun()</function> generates a slot for a member method of a particular instance.<literal>$3</literal> will be replaced by the output parameter name of the C++ method and <literal>$4</literal> will be replaced by the return of the C function when this initialization is used by gmmproc. For convenience, <literal>$1</literal> will also be replaced by the C++ type without the ampersand (&amp;) and <literal>$2</literal> will be replaced by the C type.<literal>$3</literal> will be replaced by the parameter name when this conversion is used by gmmproc.<literal>Gtk::PACK_EXPAND_PADDING</literal>: Extra space is filled with padding. The widgets will be spaced out evenly, but their sizes won't change - there will be empty space between the widgets instead.<literal>Gtk::PACK_EXPAND_WIDGET</literal>: Extra space is taken up by increasing the child widget size, without changing the amount of space between widgets.<literal>Gtk::PACK_SHRINK</literal>: Space is contracted to the child widget size. The widget will take up just-enough space and never expand.<literal>Gtk::UPDATE_CONTINUOUS</literal> - This is the default. The <literal>value_changed</literal> signal is emitted continuously, i.e. whenever the slider is moved by even the tiniest amount.<literal>Gtk::UPDATE_DELAYED</literal> - The <literal>value_changed</literal> signal is emitted when the user releases the mouse button, or if the slider stops moving for a short period of time.<literal>Gtk::UPDATE_DISCONTINUOUS</literal> - The <literal>value_changed</literal> signal is only emitted once the slider has stopped moving and the user has released the mouse button.<literal>LINGUAS</literal> contains an alphabetically sorted list of codes identifying the languages for which your program is translated (comment lines starting with a <literal>#</literal> are ignored). Each language code listed in the <literal>LINGUAS</literal> file must have a corresponding <literal>.po</literal> file. So, if your program has German and Japanese translations, your <literal>LINGUAS</literal> file would look like this:<literal>POTFILES.in</literal> is a list of paths to all files which contain strings marked up for translation, starting from the project root directory. So for example, if your project sources were located in a subdirectory named <literal>src</literal>, and you had two files that contained strings that should be translated, your <literal>POTFILES.in</literal> file might look like this:<literal>actions</literal> indicates the Drag and Drop actions which this destination can receive - see the description above.<literal>actions</literal> is an ORed combination of values, which specified which Drag and Drop operations will be possible from this source - for instance, copy, move, or link. The user can choose between the actions by using modifier keys, such as <keycap>Shift</keycap> to change from <literal>copy</literal> to <literal>move</literal>, and this will be shown by a different cursor.<literal>begin_print</literal>: You must handle this signal, because this is where you create and set up a <classname>Pango::Layout</classname> using the provided <classname>Gtk::PrintContext</classname>, and break up your printing output into pages.<literal>done</literal>: This signal is emitted when printing is finished, meaning when the print data is spooled. Note that the provided <literal>Gtk::PrintOperationResult</literal> may indicate that an error occurred. In any case you probably want to notify the user about the final status.<literal>drag_begin</literal>: Provides DragContext.<literal>drag_data_delete</literal>: Gives the source the opportunity to delete the original data if that's appropriate.<literal>drag_data_get</literal>: Provides <literal>info</literal> about the dragged data format, and a <literal>Gtk::SelectionData</literal> structure, in which you should put the requested data.<literal>drag_data_received</literal>: Provides <literal>info</literal> about the dragged data format, and a <literal>Gtk::SelectionData</literal> structure which contains the dropped data. You should call the <methodname>drag_finish()</methodname> method of the <literal>DragContext</literal> to indicate whether the operation was successful.<literal>drag_drop</literal>: Provides DragContext and coordinates. You can call <methodname>drag_get_data()</methodname>, which triggers the <literal>drag_data_get</literal> signal in the source widget, and then the <literal>drag_data_received</literal> signal in the destination widget.<literal>drag_end</literal>: Provides DragContext.<literal>drag_motion</literal>: Provides DragContext and coordinates. You can call the <methodname>drag_status()</methodname> method of the DragContext to indicate which action will be accepted.<literal>draw_page</literal>: You must handle this signal, which provides a <classname>PrintContext</classname> and a page number. The <classname>PrintContext</classname> should be used to create a <classname>Cairo::Context</classname> into which the provided page should be drawn. To render text, iterate over the <classname>Pango::Layout</classname> you created in the <literal>begin_print</literal> handler.<literal>end_print</literal>: A handler for it is a safe place to free any resources related to a <classname>PrintOperation</classname>. If you have your custom class that inherits from <classname>PrintOperation</classname>, it is naturally simpler to do it in the destructor.<literal>flags</literal> is an ORed combination of values which indicates how the widget will respond visually to Drag and Drop items.<literal>lower</literal>: lower range value<literal>page_increment</literal>: value to increment/decrement when pressing mouse button 2 on a button<literal>page_size</literal>: unused<literal>paginate</literal>: Pagination is potentially slow so if you need to monitor it you can call the <methodname>PrintOperation::set_show_progress()</methodname> method and handle this signal.<literal>request_page_setup</literal>: Provides a <classname>PrintContext</classname>, page number and <classname>Gtk::PageSetup</classname>. Handle this signal if you need to modify page setup on a per-page basis.<literal>start_button_mask</literal> is an ORed combination of values, which specify which modifier key or mouse button must be pressed to start the drag.<literal>status_changed</literal>: Emitted whenever a print job's status changes, until it is finished. Call the <methodname>PrintOperation::set_track_print_status()</methodname> method to monitor the job status after spooling. To see the status, use <methodname>get_status()</methodname> or <methodname>get_status_string()</methodname>.<literal>step_increment</literal>: value to increment/decrement when pressing mouse button 1 on a button<literal>targets</literal> is a vector of <classname>Gtk::TargetEntry</classname> elements.<literal>upper</literal>: upper range value<literal>value</literal>: value for the Spin Button<methodname>Gtk::Widget::show()</methodname> lets <application>gtkmm</application> know that we have finished setting the attributes of the widget, and that it is ready to be displayed. You can use <methodname>Gtk::Widget::hide()</methodname> to make it disappear again. The order in which you show the widgets is not important, but we do suggest that you show the top-level window last; this way, the whole window will appear with its contents already drawn. Otherwise, the user will first see a blank window, into which the widgets will be gradually drawn.<methodname>child_type_vfunc()</methodname>: Return what type of child can be added.<methodname>forall_vfunc()</methodname>: Call the same callback for each of the children.<methodname>get_preferred_height_for_width_vfunc()</methodname>: Calculate the minimum and natural height of the container, if it would be given the specified width.<methodname>get_preferred_height_for_width_vfunc()</methodname>: Calculate the minimum and natural height of the widget, if it would be given the specified width.<methodname>get_preferred_height_vfunc()</methodname>: Calculate the minimum and natural height of the container.<methodname>get_preferred_height_vfunc()</methodname>: Calculate the minimum and natural height of the widget.<methodname>get_preferred_width_for_height_vfunc()</methodname>: Calculate the minimum and natural width of the container, if it would be given the specified height.<methodname>get_preferred_width_for_height_vfunc()</methodname>: Calculate the minimum and natural width of the widget, if it would be given the specified height.<methodname>get_preferred_width_vfunc()</methodname>: Calculate the minimum and natural width of the container.<methodname>get_preferred_width_vfunc()</methodname>: Calculate the minimum and natural width of the widget.<methodname>get_request_mode_vfunc()</methodname>: (optional) Return what <literal>Gtk::SizeRequestMode</literal> is preferred by the widget.<methodname>get_request_mode_vfunc()</methodname>: Return what <literal>Gtk::SizeRequestMode</literal> is preferred by the container.<methodname>get_widget()</methodname> returns child widgets that are <function>manage()</function>ed (see the <link linkend="chapter-memory">Memory Management</link> chapter), so they will be deleted when their parent container is deleted. So, if you get only a child widget from <application>Gtk::Builder</application>, instead of a whole window, then you must either put it in a <classname>Container</classname> or delete it. <classname>Windows</classname> (such as <classname>Dialogs</classname>) cannot be managed because they have no parent container, so you must delete them at some point.<methodname>on_add()</methodname>: Add a child widget to the container.<methodname>on_draw()</methodname>: Draw on the supplied <classname>Cairo::Context</classname>.<methodname>on_map()</methodname>: (optional)<methodname>on_realize()</methodname>: Associate a <classname>Gdk::Window</classname> with the widget.<methodname>on_remove()</methodname>: Remove a child widget from the container.<methodname>on_size_allocate()</methodname> receives the actual height and width that the parent container has decided to give to your widget. This might be more than the minimum, or even more than the natural size, for instance if the top-level window has been expanded. You might choose to ignore the extra space and leave a blank area, or you might choose to expand your child widgets to fill the space, or you might choose to expand the padding between your widgets. It's your container, so you decide. Don't forget to call <methodname>set_allocation()</methodname> inside your <methodname>on_size_allocate()</methodname> implementation to actually use the allocated space that has been offered by the parent container.<methodname>on_size_allocate()</methodname>: Position the child widgets, given the height and width that the container has actually been given.<methodname>on_size_allocate()</methodname>: Position the widget, given the height and width that it has actually been given.<methodname>on_unmap()</methodname>: (optional)<methodname>on_unrealize()</methodname>: (optional) Break the association with the <classname>Gdk::Window</classname>.<methodname>run()</methodname> may return <literal>PRINT_OPERATION_RESULT_IN_PROGRESS</literal>. To track status and handle the result or error you need to implement signal handlers for the <literal>done</literal> and <literal>status_changed</literal> signals:<placeholder-1/> (or <placeholder-2/> for filenames)<placeholder-1/> Now, when objects of type <classname>MyContainer</classname> are destroyed, the button will also be deleted. It is no longer necessary to delete <varname>pButton</varname> to free the button's memory; its deletion has been delegated to the <classname>MyContainer</classname> object.<placeholder-1/> example package<type>GdkEventButton</type> is a structure containing the event's parameters, such as the coordinates of the mouse pointer at the time the button was pressed. There are several different types of <type>GdkEvent</type> structures for the various events.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1Button.html"><classname>Gtk::Button</classname></ulink>. Standard buttons, usually marked with a label or picture. Pushing one triggers an action. See the <link linkend="sec-pushbuttons">Button</link> section.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1CheckButton.html"><classname>Gtk::CheckButton</classname></ulink>. These act like ToggleButtons, but show their state in small squares, with their label at the side. They should be used in most situations which require an on/off setting. See the <link linkend="sec-checkboxes">CheckButton</link> section.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1RadioButton.html"><classname>Gtk::RadioButton</classname></ulink>. Named after the station selectors on old car radios, these buttons are used in groups for options which are mutually exclusive. Pressing one causes all the others in its group to turn off. They are similar to CheckBoxes (a small widget with a label at the side), but usually look different. See the <link linkend="sec-radio-buttons">RadioButton</link> section.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1ToggleButton.html"><classname>Gtk::ToggleButton</classname></ulink>. Unlike a normal Button, which springs back up, a ToggleButton stays down until you press it again. It might be useful as an on/off switch. See the <link linkend="sec-toggle-buttons">ToggleButton</link> section.<varname>app_exec</varname>: The command line to be used to launch this resource. This string may contain the "f" and "u" escape characters which will be expanded to the resource file path and URI respectively<varname>app_name</varname>: The name of the application that registered the resource<varname>description</varname>: A short description of the resource as a UTF-8 encoded string<varname>display_name</varname>: The name of the resource to be used for display as a UTF-8 encoded string<varname>groups</varname>: A list of groups associated with this item. Groups are essentially arbitrary strings associated with a particular resource. They can be thought of as 'categories' (such as "email", "graphics", etc) or tags for the resource.<varname>is_private</varname>: Whether this resource should be visible only to applications that have registered it or not<varname>mime_type</varname>: The MIME type of the resourceA .hg file will typically include some headers and then declare a class, using some macros to add API or behaviour to this class. For instance, <application>gtkmm</application>'s <filename>button.hg</filename> looks roughly like this: <placeholder-1/>A <classname>ComboBox</classname> may contain an <classname>Entry</classname> widget for entering of arbitrary text, by specifying <literal>true</literal> for the constructor's <literal>has_entry</literal> parameter.A <classname>Entry</classname> widget can offer a drop-down list of pre-existing choices based on the first few characters typed by the user. For instance, a search dialog could suggest text from previous searches.A <classname>Glib::Dispatcher</classname> is used for sending notifications from the worker thread to the GUI thread. The <classname>ExampleWorker</classname> class contains data which is accessed by both threads. This data is protected by a <classname>Glib::Threads::Mutex</classname>. Only the GUI thread updates the GUI.A <classname>Glib::Dispatcher</classname> object can be emitted on by the receiver thread as well as by a worker thread, although this should be done within reasonable bounds. On unix-like systems <classname>Glib::Dispatcher</classname> objects share a single common pipe, which could in theory at least fill up on a very heavily loaded system running a program with a very large number of <classname>Dispatcher</classname> objects in use. Were the pipe to fill up before the receiver thread's main loop has had an opportunity to read from it to empty it, and the receiver thread attempt to emit and so write to it when it is in that condition, the receiver thread would block on the write, so deadlocking. Where the receiver thread is to emit, a normal <classname>sigc::signal&lt;void&gt;</classname> object could of course be used instead.A <classname>Grid</classname> dynamically lays out child widgets in rows and columns. The dimensions of the grid do not need to be specified in the constructor.A <classname>Notebook</classname> has a set of stacked <literal>pages</literal>, each of which contains widgets. Labelled <literal>tabs</literal> allow the user to select the pages. <classname>Notebook</classname>s allow several sets of widgets to be placed in a small space, by only showing one page at a time. For instance, they are often used in preferences dialogs.A <classname>Plug</classname> is a special kind of Window that can be plugged into a <classname>Socket</classname>. Besides the normal properties and methods of <classname>Gtk::Window</classname>, a <classname>Plug</classname> provides a constructor that takes the ID of a <classname>Socket</classname>, which will automatically embed the <classname>Plug</classname> into the <classname>Socket</classname> that matches that ID.A <classname>ProgressBar</classname> is horizontal and left-to-right by default, but you can change it to a vertical progress bar by using the <methodname>set_orientation()</methodname> method.A <classname>RecentInfo</classname> object is essentially an object containing all of the metadata about a single recently-used file. You can use this object to look up any of the properties listed <link linkend="list-file-metadata">above</link>.A <classname>Socket</classname> is a special kind of container widget that provides the ability to embed widgets from one process into another process in a way that is transparent to the user.A <classname>SpinButton</classname> allows the user to select a value from a range of numeric values. It has an <classname>Entry</classname> widget with increment and decrement buttons at the side. Clicking the buttons causes the value to 'spin' up and down across the range of possible values. The <classname>Entry</classname> widget may also be used to enter a value directly.A <classname>ToolPalette</classname> is similar to a <classname>Toolbar</classname> but can contain a grid of items, categorized into groups. The user may hide or expand each group. As in a toolbar, the items may be displayed as only icons, as only text, or as icons with text.A <classname>sigc::signal</classname> object should be regarded as owned by the thread which created it. Only that thread should connect a <classname>sigc::slot</classname> object to the signal object, and only that thread should <methodname>emit()</methodname> or call <methodname>operator()()</methodname> on the signal, or null any connected <classname>sigc::slot</classname> object. It follows (amongst other things) that any signal object provided by a <application>gtkmm</application> widget should only be operated on in the main GUI thread and any object deriving from <classname>sigc::trackable</classname> having its non-static methods referenced by slots connected to the signal object should only be destroyed in that thread.A <classname>sigc::slot</classname> object created by a call to <function>sigc::mem_fun()</function> which references a method of a class deriving from <classname>sigc::trackable</classname> should never be copied to another thread, nor destroyed by a different thread than the one which created it. (One consequence of this is that <methodname>Glib::Threads::Thread::create()</methodname> should not be called with a slot argument created by a call to <function>sigc::mem_fun()</function> which represents a method of such a class. It is however safe to pass <methodname>Glib::Threads::Thread::create()</methodname> a function object representing such a method by using, say, <function>boost::bind()</function> or, in C++11, <function>std::bind()</function> or a C++11 lambda expression.)A child widget can be added to the <classname>EventBox</classname> using:A little example follows. To use the example just execute it from a terminal; it doesn't create a window. It will create a pipe named <literal>testfifo</literal> in the current directory. Then start another shell and execute <literal>echo "Hello" &gt; testfifo</literal>. The example will print each line you enter until you execute <literal>echo "Q" &gt; testfifo</literal>.A nifty feature of Glib (one of the libraries underlying <application>gtkmm</application>) is the ability to have it check for data on a file descriptor for you. This is especially useful for networking applications. The following method is used to do this:A properly internationalized application will not make assumptions about the number of bytes in a character. That means that you shouldn't use pointer arithmetic to step through the characters in a string, and it means you shouldn't use <classname>std::string</classname> or standard C functions such as <function>strlen()</function> because they make the same assumption.A rule to which there may be exceptions: If the virtual C function returns a pointer to an object derived from <classname>GObject</classname>, i.e. a reference-counted object, then the virtual C++ function shall return a <classname>Glib::RefPtr&lt;&gt;</classname> object. One of the extra arguments <parameter>refreturn</parameter> or <parameter>refreturn_ctype</parameter> is required.A smartpointer acts much like a normal pointer. Here are a few examples.A target can be in a variety of binary formats. This chapter, and the examples, assume that the data is 8-bit text. This would allow us to use an XML format for the clipboard data. However this would probably not be appropriate for binary data such as images. <classname>Gtk::Clipboard</classname> provides overloads that allow you to specify the format in more detail if necessary.AM_CPPFLAGSAM_CPPFLAGS = ... -DPROGRAMNAME_LOCALEDIR=\"${PROGRAMNAME_LOCALEDIR}\"AM_CXXFLAGSATKAboutDialogAccessing widgetsActionsActivity ModeAdd <literal>INTLTOOL_FILES</literal> to the <literal>EXTRA_DIST</literal> list of files. This ensures that when you do a <command>make dist</command>, these commands will be included in the source tarball.Add <literal>po</literal> to the <literal>SUBDIRS</literal> variable. Without this, your translations won't get built and installed when you build the programAdd a default constructor.Add methods to wrap parts of the C API.Add rows to the model with the <methodname>append()</methodname>, <methodname>prepend()</methodname>, or <methodname>insert()</methodname> methods.Adding Items to the List of Recent FilesAdding RowsAdding View ColumnsAdding child rowsAdding properties, and ensuring that they interact properly with each other, is relatively difficult to correct in the C library, but it is possible, so do file a bug and try to send a patch to the relevant maintainer.Adding widgetsAdditional command-line flags passed to the <filename>generate_wrap_init.pl</filename> script, such as the C++ namespace and the parent directory prefix of include files.Additionally, mouse button 3 can be used to jump directly to the <literal>upper</literal> or <literal>lower</literal> values.Adjustment InternalsAdjustmentsAfter a <classname>Socket</classname> or <classname>Plug</classname> object is realized, you can obtain its ID with its <methodname>get_id()</methodname> function. This ID can then be shared with other processes so that other processes know how to connect to each other.After appending rows to this model, you should provide the model to the <classname>ComboBox</classname> with the <methodname>set_model()</methodname> method. Then use the <methodname>pack_start()</methodname> or <methodname>pack_end()</methodname> methods to specify what columns will be displayed in the ComboBox. As with the TreeView you may either use the default cell renderer by passing the <classname>TreeModelColumn</classname> to the pack methods, or you may instantiate a specific <classname>CellRenderer</classname> and specify a particular mapping with either <methodname>add_attribute()</methodname> or <methodname>set_cell_data_func()</methodname>. Note that these methods are in the <classname>CellLayout</classname> base class.After building and running this program, try resizing the window to see the behaviour. Also, try playing with the options to <methodname>pack_start()</methodname> while reading the <link linkend="sec-boxes">Boxes</link> section.After drawing the outline, we go around the clock and draw ticks for every hour, with a larger tick at 12, 3, 6, and 9. Now we're finally ready to implement the time-keeping functionality of the clock, which simply involves getting the current values for hours, minutes and seconds, and drawing the hands at the correct angles.After putting the source code in <literal>simple.cc</literal> you can compile the above program with <application>gcc</application> using: <placeholder-1/> Note that you must surround the <literal>pkg-config</literal> invocation with backquotes. Backquotes cause the shell to execute the command inside them, and to use the command's output as part of the command line. Note also that <literal>simple.cc</literal> must come before the <literal>pkg-config</literal> invocation on the command line.After selecting the <guimenuitem>Recent Files Dialog</guimenuitem> menu item, you should see something similar to the following window.After setting the correct moduleset, you need to tell <application>jhbuild</application> which module or modules to build. To build <application>gtkmm</application> and all of its dependencies, set <varname>modules</varname> like so: <placeholder-1/>After starting <filename>socket</filename>, you should see the following output in the terminal:After which you should see something like the following:After you've created and set up the filter to match only the items you want, you can apply a filter to a chooser widget with the <methodname>RecentChooser::add_filter()</methodname> function.After you've finished creating your path, you still haven't drawn anything visible yet. To make the path visible, you must use the function <methodname>stroke()</methodname> which will stroke the current path with the line width and style specified in your <classname>Cairo::Context</classname> object. After stroking, the current path will be cleared so that you can start on your next path.After you've installed all of the dependencies, download the <application>gtkmm</application> source code, unpack it, and change to the newly created directory. <application>gtkmm</application> can be built and installed with the following sequence of commands:After you've installed the git version of <application>gtkmm</application>, you're ready to start using and experimenting with it. In order to use the new version of <application>gtkmm</application> you've just installed, you need to set some environment variables so that your <filename>configure</filename> script knows where to find the new libraries. Fortunately, <application>jhbuild</application> offers an easy solution to this problem. Executing the command <command>jhbuild shell</command> will start a new shell with all of the correct environment variables set. Now if you re-configure and build your project just as you usually do, it should link against the newly installed libraries. To return to your previous environment, simply exit the <application>jhbuild</application> shell.AhlstedtAlignmentAll <application>gtkmm</application> programs must include certain <application>gtkmm</application> headers; <literal>gtkmm.h</literal> includes the entire <application>gtkmm</application> kit. This is usually not a good idea, because it includes a megabyte or so of headers, but for simple programs, it suffices.All container widgets derive from <classname>Gtk::Container</classname>, not always directly. Some container widgets, such as <classname>Gtk::Grid</classname> can hold many child widgets, so these typically have more complex interfaces. Others, such as <classname>Gtk::Frame</classname> contain only one child widget.All deprecated API was removed in <application>gtkmm</application> 3.0, though there will be new deprecations in future versions.All mentions of <varname>skeleton</varname> should be replaced by the correct name of the C library you are wrapping, such as "something" or "libsomething". In the same manner, all instances of <varname>SKELETON</varname> should be replaced by "SOMETHING" or "LIBSOMETHING", and all occurrences of <varname>Skeleton</varname> changed to "Something".Also, the value can be drawn in different positions relative to the trough, specified by the <methodname>set_value_pos()</methodname> method.Alternatively, if a complete list of possible entries would be too large or too inconvenient to generate, a callback slot may instead be specified with <methodname>set_match_func()</methodname>. This is also useful if you wish to match on a part of the string other than the start.Alternatively, you can let a widget's container control when the widget is destroyed. In most cases, you want a widget to last only as long as the container it is in. To delegate the management of a widget's lifetime to its container, first create it with <function>Gtk::manage()</function> and pack it into its container with <methodname>Gtk::Container::add()</methodname>, <methodname>Gtk::Box::pack_start()</methodname>, or a similar method. Now the widget will be destroyed whenever its container is destroyed.Although <application>glib</application> is itself thread-safe, any <application>glibmm</application> wrappers which use <application>libsigc++</application> will not be. So for example, only the thread in which a main loop runs should call <methodname>Glib::SignalIdle::connect()</methodname>, <methodname>Glib::SignalIO::connect()</methodname>, <methodname>Glib::SignalTimeout::connect()</methodname>, <methodname>Glib::SignalTimeout::connect_seconds</methodname> for that main loop, or manipulate any <classname>sigc::connection</classname> object returned by them.Although <application>gtkmm</application> widget instances have lifetimes and scopes just like those of other C++ classes, <application>gtkmm</application> has an optional time-saving feature that you will see in some of the examples. <function>Gtk::manage()</function> allows you to say that a child widget is owned by the container into which you place it. This allows you to <function>new</function> the widget, add it to the container and forget about deleting it. You can learn more about <application>gtkmm</application> memory management techniques in the <link linkend="chapter-memory">Memory Management chapter</link>.Although Cairo can render text, it's not meant to be a replacement for Pango. Pango is a better choice if you need to perform more advanced text rendering such as wrapping or ellipsizing text. Drawing text with Cairo should only be done if the text is part of a graphic.Although the <literal>custom_widget_apply</literal> signal provides the widget you previously created, to simplify things you can keep the widgets you expect to contain some user input as class members. For example, let's say you have a <classname>Gtk::Entry</classname> called <literal>m_Entry</literal> as a member of your <classname>CustomPrintOperation</classname> class: <placeholder-1/>Although the name <classname>EventBox</classname> emphasises the event-handling method, the widget can also be used for clipping (and more; see the example below).Although we have shown the compilation command for the simple example, you really should use the automake and autoconf tools, as described in "Autoconf, Automake, Libtool", by G. V. Vaughan et al. The examples used in this book are included in the <application>gtkmm-documentation</application> package, with appropriate build files, so we won't show the build commands in future. You'll just need to find the appropriate directory and type <literal>make</literal>.Although you can specify the layout and appearance of windows and widgets with C++ code, you will probably find it more convenient to design your user interfaces with <literal>Glade</literal> and load them at runtime with <literal>Gtk::Builder</literal>. See the <link linkend="chapter-builder">Glade and Gtk::Builder</link> chapter.Although you can theoretically implement your own Model, you will normally use either the <classname>ListStore</classname> or <classname>TreeStore</classname> model classes.Although you can use C++ code to instantiate and arrange widgets, this can soon become tedious and repetitive. And it requires a recompilation to show changes. The <application>Glade</application> application allows you to layout widgets on screen and then save an XML description of the arrangement. Your application can then use the <application>Gtk::Builder</application> API to load that XML file at runtime and obtain a pointer to specifically named widget instances.Although your container might have its own method to set the child widgets, you should still provide an implementation for the virtual <methodname>on_add()</methodname> and <methodname>on_remove()</methodname> methods from the base class, so that the add() and remove() methods will do something appropriate if they are called.Although, in most cases, the programmer will prefer to allow containers to automatically destroy their children using <function>Gtk::manage()</function> (see below), the programmer is not required to use <function>Gtk::manage()</function>. The traditional <literal>new</literal> and <literal>delete</literal> operators may also be used. <placeholder-1/> Here, the programmer deletes <varname>pButton</varname> to prevent a memory leak.An <classname>Assistant</classname> splits a complex operation into steps. Each step is a page, containing a header, a child widget and an action area. The Assistant's action area has navigation buttons which update automatically depending on the type of the page, set with <methodname>set_page_type()</methodname>.An <classname>Entry</classname> widget can show a progress bar inside the text area, under the entered text. The progress bar will be shown if the <methodname>set_progress_fraction()</methodname> or <methodname>set_progress_pulse_step()</methodname> methods are called.An <classname>Entry</classname> widget can show an icon at the start or end of the text area. The icon can be specifed by methods such as <methodname>set_icon_from_pixbuf()</methodname> or <methodname>set_icon_from_icon_name()</methodname>. An application can respond to the user pressing the icon by handling the <methodname>signal_icon_press</methodname> signal.An <classname>InfoBar</classname> may show small items of information or ask brief questions. Unlike a <classname>Dialog</classname>, it appears at the top of the current window instead of opening a new window. Its API is very similar to the <link linkend="chapter-dialogs">Gtk::Dialog</link> API.An improved Hello WorldAnastasovAnd here's an excerpt from a <application>gdb</application> session. <placeholder-1/> The exception is caught in <application>glibmm</application>, and the program ends with a call to <function>g_error()</function>. Other exceptions may result in different behaviour, but in any case the exception from a signal handler is caught in <application>glibmm</application> or <application>gtkmm</application>, and <application>gdb</application> can't see where it was thrown.Another thing to note about this example is that we made the call to <methodname>connect()</methodname> twice for the same signal object. This is perfectly fine - when the button is clicked, both signal handlers will be called.Another way of destroying the connection is your signal handler. It has to be of the type <classname>sigc::slot&lt;bool&gt;</classname>. As you see from the definition your signal handler has to return a value of the type <literal>bool</literal>. A definition of a sample method might look like this: <placeholder-1/>Another workaround is to add a <function>*_construct()</function> function that the C++ constructor can call after instantiating its own type. For instance, <placeholder-1/>Any <classname>sigc::connection</classname> object should be regarded as owned by the thread in which the method returning the <classname>sigc::connection</classname> object was called. Only that thread should call <classname>sigc::connection</classname> methods on the object.Any additional non-generated <filename>.h</filename> and <filename>.cc</filename> source files may be placed in <filename>skeleton/skeletonmm/</filename> and listed in <filename>skeleton/skeletonmm/filelist.am</filename>, typically in the <varname>files_extra_h</varname> and <varname>files_extra_cc</varname> variables.Application LifetimeApplying TagsAs a first step to porting your source code to <application>gtkmm</application>-3.0 you should probably ensure that your application builds with the deprecated <application>gtkmm</application>-2.4 API disabled, by defining macro such as GTKMM_DISABLE_DEPRECATED. There are some autotools macros that can help with this by defining them optionally at build time. See the <ulink url="https://live.gnome.org/gtkmm/PortingToGtkmm3">gtkmm 3 porting wiki page</ulink> for more details.As before, almost all of the interesting stuff is done in the draw signal handler <methodname>on_draw()</methodname>. Before we dig into the draw signal handler, notice that the constructor for the <classname>Clock</classname> widget connects a handler function <methodname>on_timeout()</methodname> to a timer with a timeout period of 1000 milliseconds (1 second). This means that <methodname>on_timeout()</methodname> will get called once per second. The sole responsibility of this function is to invalidate the window so that <application>gtkmm</application> will be forced to redraw it.As mentioned above, each <classname>TextView</classname> has a <classname>TextBuffer</classname>, and one or more <classname>TextView</classname>s can share the same <classname>TextBuffer</classname>.As mentioned earlier, <classname>Gtk::Adjustment</classname> can emit signals. This is, of course, how updates happen automatically when you share an <classname>Adjustment</classname> object between a <classname>Scrollbar</classname> and another adjustable widget; all adjustable widgets connect signal handlers to their adjustment's <literal>value_changed</literal> signal, as can your program.As well as renaming the directories, we should rename some of the source files. For instance: <placeholder-1/> A number of the skeleton files must still be filled in with project-specific content later.As will be explained in the <link linkend="chapter-adjustment">Adjustment</link> section, all Range widgets are associated with a <classname>Adjustment</classname> object. To change the lower, upper, and current values used by the widget you need to use the methods of its <classname>Adjustment</classname>, which you can get with the <methodname>get_adjustment()</methodname> method. The <classname>Range</classname> widgets' default constructors create an <classname>Adjustment</classname> automatically, or you can specify an existing <classname>Adjustment</classname>, maybe to share it with another widget. See the <link linkend="chapter-adjustment">Adjustments</link> section for further details.As with <classname>Scrollbar</classname>s, the orientation can be either horizontal or vertical. The default constructor creates an <classname>Adjustment</classname> with all of its values set to <literal>0.0</literal>. This isn't useful so you will need to set some <classname>Adjustment</classname> details to get meaningful behaviour.Aside from the fact that connected slots always execute in the receiver thread, <classname>Glib::Dispatcher</classname> objects are similar to <classname>sigc::signal&lt;void&gt;</classname> objects. They therefore cannot pass unbound arguments nor return a value. The best way to pass unbound arguments is with a thread-safe (asynchronous) queue. At the time of writing <application>glibmm</application> does not have one, although most people writing multi-threaded code will have one available to them (they are relatively easy to write although there are subtleties in combining thread safety with strong exception safety).AspectFrameAssistantAssuming the displayed size of stringsAsynchronous operationsAt install time, the <filename>.po</filename> files are converted to a binary format (with the extension <filename>.mo</filename>) and placed in a system-wide directory for locale files, for example <filename>/usr/share/locale/</filename>.At the application development level, <application>gtkmm</application>'s printing API provides dialogs that are consistent across applications and allows use of Cairo's common drawing API, with Pango-driven text rendering. In the implementation of this common API, platform-specific backends and printer-specific drivers are used.At the least, the <function>_new()</function> function should not use any private API (functions that are only in a .c file). Even when there are no functions, we can sometimes reimplement 2 or 3 lines of code in a <function>_new()</function> function as long as those lines of code use API that is available to us.At the moment, we have separate tools for generating different parts of these <filename>.defs</filename>, so we split them up into separate files. For instance, in the <filename>gtk/src</filename> directory of the <application>gtkmm</application> sources, you will find these files: <placeholder-1/>Automatically-stored editable cells.Basic Type equivalentsBasic TypesBasicsBecause the user may enter arbitrary text, an active model row isn't enough to tell us what text the user has entered. Therefore, you should retrieve the <classname>Entry</classname> widget with the <methodname>ComboBox::get_entry()</methodname> method and call <methodname>get_text()</methodname> on that.Because this automatic transformation is not always appropriate, you might want to provide hand-written text for a particular method. You can do this by copying the XML node for the function from your <filename>something_docs.xml</filename> file to the <filename>something_docs_override.xml</filename> file and changing the contents.Before attempting to install <application>gtkmm</application> 3.0, you might first need to install these other packages.Below is a short example to illustrate these functions. This example makes use of the Frame widget to better demonstrate the label styles. (The Frame widget is explained in the <link linkend="sec-frame">Frame</link> section.) It is possible that the first character in <literal>m_Label_Normal</literal> is shown underlined only when you press the <keycap>Alt</keycap> key.BernhardBesides indicating the amount of progress that has occured, the progress bar can also be used to indicate that there is some activity; this is done by placing the progress bar in <emphasis>activity mode</emphasis>. In this mode, the progress bar displays a small rectangle which moves back and forth. Activity mode is useful in situations where the progress of an operation cannot be calculated as a value range (e.g., receiving a file of unknown length).Binding extra argumentsBjarne Stroustrup, "The C++ Programming Language" Forth Edition - section 34.3Box Packing 1Box Packing 2BoxesBuilding <application>gtkmm</application> on Win32But unlike most smartpointers, you can't use the * operator to access the underlying instance.But unlike normal pointers, <classname>RefPtr</classname>s are automatically initialized to null so you don't need to remember to do that yourself.ButtonButton boxes are a convenient way to quickly arrange a group of buttons. Their orientation can be either horizontal or vertical.Button boxes support several layout styles. The style can be retrieved and changed using <methodname>get_layout()</methodname> and <methodname>set_layout()</methodname>.ButtonBoxButtonBoxesButtonsButtons are added to a <classname>ButtonBox</classname> with the <methodname>add()</methodname> method.By convention, glib/GTK+-style objects have <function>*_new()</function> functions, such as <function>example_widget_new()</function> that do nothing more than call <function>g_object_new()</function> and return the result. The input parameters are supplied to <function>g_object_new()</function> along with the names of the properties for which they are values. For instance, <placeholder-1/>By convention, structs are declared in glib/GTK+-style headers like so: <placeholder-1/>By default, <application>gtkmm</application> will be installed under the <filename>/usr/local</filename> directory. On some systems you may need to install to a different location. For instance, on Red Hat Linux systems you might use the <literal>--prefix</literal> option with configure, like so: <screen>
# ./configure --prefix=/usr
</screen>By default, <application>jhbuild</application>'s configuration is configured to install all software built with <application>jhbuild</application> under the <filename>/opt/gnome</filename> prefix. You can choose a different prefix, but it is recommended that you keep this prefix different from other software that you've installed (don't set it to <filename>/usr</filename>!) If you've followed the jhbuild instructions then this prefix belongs to your user, so you don't need to run jhbuild as <literal>root</literal>.By default, <methodname>PrintOperation::run()</methodname> returns when a print operation is completed. If you need to run a non-blocking print operation, call <methodname>PrintOperation::set_allow_async()</methodname>. Note that <methodname>set_allow_async()</methodname> is not supported on all platforms, however the <literal>done</literal> signal will still be emitted.By default, only single rows can be selected, but you can allow multiple selection by setting the mode, like so: <placeholder-1/>By default, your signal handlers are called after any previously-connected signal handlers. However, this can be a problem with the X Event signals. For instance, the existing signal handlers, or the default signal handler, might return <literal>true</literal> to stop other signal handlers from being called. To specify that your signal handler should be called before the other signal handlers, so that it will always be called, you can specify <literal>false</literal> for the optional <literal>after</literal> parameter. For instance, <placeholder-1/>By deriving directly from <classname>Gtk::Widget</classname> you can do all the drawing for your widget directly, instead of just arranging child widgets. For instance, a <classname>Gtk::Label</classname> draws the text of the label, but does not do this by using other widgets.By overriding <methodname>forall_vfunc()</methodname> you can allow applications to operate on all of the container's child widgets. For instance, <methodname>show_all_children()</methodname> uses this to find all the child widgets and show them.C programmers use <function>sprintf()</function> to compose and concatenate strings. C++ favours streams, but unfortunately, this approach makes translation difficult, because each fragment of text is translated separately, without allowing the translators to rearrange them according to the grammar of the language.C typeC++ typeCairo and PangoCall <methodname>add_drag_dest()</methodname> to allow items or groups to be dragged from the tool palette to a particular destination widget. You can then use <methodname>get_drag_item()</methodname> to discover which ToolItem or ToolItemGroup is being dragged. You can use <literal>dynamic_cast</literal> to discover whether it is an item or a group. For instance, you might use this in your <literal>drag_data_received</literal> signal handler, to add a dropped item, or to show a suitable icon while dragging.Call <methodname>show()</methodname> to display the widget.CastingCells in a <classname>TreeView</classname> can be edited in-place by the user. To allow this, use the <classname>Gtk::TreeView</classname><methodname>insert_column_editable()</methodname> and <methodname>append_column_editable()</methodname> methods instead of <methodname>insert_column()</methodname> and <methodname>append_column()</methodname>. When these cells are edited the new values will be stored immediately in the Model. Note that these methods are templates which can only be instantiated for simple column types such as <classname>Glib::ustring</classname>, int, and long.Changes in <application>gtkmm</application> 3Changing the layout of a window "on the fly", to make some extra widgets appear, for instance, is complex. It requires tedious recalculation of every widget's position.Changing the selectionChapter on "Drawing with Cairo".Chapter on "Multi-threaded programs".Chapter on "Printing".Chapter on "Recent Files".Chapter on "Timeouts".Chapter on "Working with gtkmm's Source Code".Chapter on Keyboard Events.CheckButtonCheckboxesChecking for nullChild widgets can span multiple rows or columns, using <methodname>attach()</methodname>, or added next to an existing widget inside the grid with <methodname>attach_next_to()</methodname>. Individual rows and columns of the grid can be set to have uniform height or width with <methodname>set_row_homogeneous()</methodname> and <methodname>set_column_homogeneous()</methodname>.ChrisClass Scope widgetsClass macrosClipboard - IdealClipboard - SimpleColorChooserDialogCombo BoxesComboBoxComboBox with EntryComboBox with an EntryComboBoxTextComboBoxText with EntryComparison with other signalling systemsComposition of stringsConnect any signals you wish to use to the appropriate handlers.Connecting Plugs and SocketsConnecting signal handlersConst Objects used via <classname>RefPtr</classname>: If the object should not be changed by the function, then make sure that the object is const, even if the <classname>RefPtr</classname> is already const. For instance, <code>const Glib::RefPtr&lt;const Gtk::FileFilter&gt;&amp; filter</code>.ConstnessConstructor macrosConstructorsContainer WidgetsContrary to other events, keyboard events are first sent to the toplevel window (<classname>Gtk::Window</classname>), where it will be checked for any keyboard shortcuts that may be set (accelerator keys and mnemonics, used for selecting menu items from the keyboard). After this (and assuming the event wasn't handled), it is sent to the widget which has focus, and the propagation begins from there.ContributingCopyCopyingCopying the skeleton projectCreate a <classname>Plug</classname> independantly from any particular <classname>Socket</classname> and pass the ID of the <classname>Plug</classname> to other processes that need to use it. The ID of the <classname>Plug</classname> can be associated with a particular <classname>Socket</classname> object using the <methodname>Socket::add_id()</methodname> function. This is the approach used in the example below.Create a <classname>Socket</classname> object in one process and pass the ID of that <classname>Socket</classname> to another process so that it can create a <classname>Plug</classname> object by specifying the given <classname>Socket</classname> ID in its constructor. There is no way to assign a <classname>Plug</classname> to a particular <classname>Socket</classname> after creation, so you must pass the <classname>Socket</classname> ID to the <classname>Plug</classname>'s constructor.Create a sub-directory named <literal>po</literal> in your project's root directory. This directory will eventually contain all of your translations. Within it, create a file named <literal>LINGUAS</literal> and a file named <literal>POTFILES.in</literal>. It is common practice to also create a <literal>ChangeLog</literal> file in the <literal>po</literal> directory so that translators can keep track of translation changes.Create your own signals instead of passing pointers around. Objects can communicate with each other via signals and signal handlers. This is much simpler than objects holding pointers to each other and calling each other's methods. <application>gtkmm</application>'s classes uses special versions of <classname>sigc::signal</classname>, but you should use normal <classname>sigc::signal</classname>s, as described in the <application>libsigc++</application> documentation.Creating .hg and .ccg filesCreating an AdjustmentCreating your own signalsCummingCurrently, <application>gettext</application> does not support non-ASCII characters (i.e. any characters with a code above 127) in source code. For instance, you cannot use the copyright sign (©).Custom ContainerCustom ContainersCustom WidgetCustom WidgetsDISTCLEANFILES = ... intltool-extract \
                 intltool-merge \
                 intltool-update \
                 po/.intltool-merge-cacheDanielDavidDeclare a variable of the type of <classname>Widget</classname> you wish to use, generally as member variable of a derived container class. You could also declare a pointer to the widget type, and then create it with <literal>new</literal> in your code. Even when using the widget via a pointer, it's still probably best to make that pointer a member variable of a container class so that you can access it later.Default formattingDefine <literal>INTLTOOL_FILES</literal> as: <placeholder-1/>Defines a custom clipboard target, though the format of that target is still text.DependenciesDereferencingDesigners without programming skills can create and edit UIs.DialogsDialogs are used as secondary windows, to provide specific information or to ask questions. <classname>Gtk::Dialog</classname> windows contain a few pre-packed widgets to ensure consistency, and a <methodname>run()</methodname> method which blocks until the user dismisses the dialog.Different applications contain different types of data, and they might make that data available in a variety of formats. <application>gtkmm</application> calls these data types <literal>target</literal>s.Different join types in CairoDisconnecting signal handlersDiscovering the available targetsDo an extra <function>reference()</function> on the return value of an overridden <function>something_vfunc()</function> function in the C callback function, in case the calling C function expects it to provide a reference.Do an extra <function>reference()</function> on the return value of the <function>on_something()</function> virtual method, in case the C function does not provide a reference.Do an extra <function>reference()</function> on the return value of the <function>something_vfunc()</function> function, in case the virtual C function does not provide a reference.Do an extra <function>reference()</function> on the return value, in case the C function does not provide a reference.Do not generate a C callback function for the signal. Use this when you must generate the callback function by hand.Do not generate a C callback function for the vfunc. Use this when you must generate the callback function by hand.Do not generate a definition of the vfunc in the <filename>.cc</filename> file. Use this when you must generate the vfunc by hand.Do not generate an <function>on_something()</function> virtual method to allow easy overriding of the default signal handler. Use this when adding a signal with a default signal handler would break the ABI by increasing the size of the class's virtual function table.DocumentationDocumentation build structureDrag and DropDragContextDrawing Arcs and CirclesDrawing Area - ArcsDrawing Area - ImageDrawing Area - LinesDrawing Area - TextDrawing Area - Thin LinesDrawing Curved LinesDrawing ImagesDrawing Straight LinesDrawing TextDrawing Text with PangoDrawing counter-clockwiseDrawing thin linesDrawing with relative coordinatesDuring a <literal>move</literal>, the source widget will also emit this signal: <placeholder-1/>Dynamic allocation with manage() and add()Dynamic allocation with new and deleteEach <classname>Cairo::Context</classname> is associated with a particular <classname>Gdk::Window</classname>, so the first line of the above example creates a <classname>Gtk::DrawingArea</classname> widget and the second line uses its associated <classname>Gdk::Window</classname> to create a <classname>Cairo::Context</classname> object. The final two lines change the graphics state of the context.Each <classname>Gtk::TextBuffer</classname> uses a <classname>Gtk::TextBuffer::TagTable</classname>, which contains the <classname>Tag</classname>s for that buffer. 2 or more <classname>TextBuffer</classname>s may share the same <classname>TagTable</classname>. When you create <classname>Tag</classname>s you should add them to the <classname>TagTable</classname>. For instance:Each <classname>Gtk::TreeView</classname> has an associated <classname>Gtk::TreeModel</classname>, which contains the data displayed by the <classname>TreeView</classname>. Each <classname>Gtk::TreeModel</classname> can be used by more than one <classname>Gtk::TreeView</classname>. For instance, this allows the same underlying data to be displayed and edited in 2 different ways at the same time. Or the 2 Views might display different columns from the same Model data, in the same way that 2 SQL queries (or "views") might show different fields from the same database table.Each item in the list of recently used files is identified by its URI, and can have associated metadata. The metadata can be used to specify how the file should be displayed, a description of the file, its mime type, which application registered it, whether it's private to the registering application, and several other things.Each line contains one horizontal <classname>Box</classname> with several buttons. Each of the buttons on a line is packed into the <classname>Box</classname> with the same arguments to the <methodname>pack_start()</methodname> method.Editable CellsElstnerEmitted when the button is pressed and released.Emitted when the button is pressed.Emitted when the button is released.Emitted when the mouse pointer leaves the button's window.Emitted when the mouse pointer moves over the button's window.EntryEntry CompletionEntry Completion ExampleEntry Icon ExampleEntry IconsEntry ProgressEntry Progress ExampleEntry widgets allow the user to enter text. You can change the contents with the <methodname>set_text()</methodname> method, and read the current contents with the <methodname>get_text()</methodname> method.Entry with IconEntry with Progress BarEnumerations.Event PropagationEvent propagation means that, when an event is emitted on a particular widget, it can be passed to its parent widget (and that widget can pass it to its parent, and so on) and, if the parent has an event handler, that handler will be called.EventBoxExampleExample Application: Creating a Clock with CairoExamplesExceptions in signal handlersExpecting UTF8Export to PDFExtending the print dialogFerreiraFileChooserFileChooserDialogFiltering Recent FilesFinally, check the status. For instance, <placeholder-1/>Finally, to let your program use the translation for the current locale, add this code to the beginning of your <filename>main.cc</filename> file, to initialize gettext. <placeholder-1/>First create the <classname>Action</classname>s and add them to an <classname>ActionGroup</classname>, with <methodname>ActionGroup::add()</methodname>.First we instantiate an object stored in a <classname>RefPtr</classname> smartpointer called <literal>app</literal>. This is of type <classname>Gtk::Application</classname>. Every <application>gtkmm</application> program must have one of these. We pass our command-line arguments to its create() method. It takes the arguments it wants, and leaves you the rest, as we described earlier.First, let's look at a simple example where an exception is thrown from a normal function (no signal handler). <placeholder-1/>FontChooserDialogFor a CellRendererToggle, you would set the <emphasis>activatable</emphasis> property instead.For all macros processing method signatures except <function>_WRAP_SIGNAL()</function> and <function>_WRAP_VFUNC()</function> it is also possible to make the parameters optional so that extra C++ methods are generated without the specified optional parameter. For example, say that the following <function>*_new()</function> function were being wrapped as a constructor in the <classname>Gtk::ToolButton</classname> class: <placeholder-1/> Also, say that the C API allowed NULL for the function's <parameter>label</parameter> parameter so that that parameter is optional. It would be possible to have <command>gmmproc</command> generate the original constructor (with all the parameters) along with an additional constructor without that optional parameter by appending a <literal>{?}</literal> to the parameter name like so: <placeholder-2/> In this case, two constructors would be generated: One with the optional parameter and one without it.For all the macros that process method signatures, it is possible to specify a different order for the C++ parameters than the existing order in the C function, virtual function or signal. For example, say that the following C function were being wrapped as a C++ method for the <classname>Gtk::Widget</classname> class: <placeholder-1/> However, changing the order of the C++ method's two parameters is necessary. Something like the following would wrap the function as a C++ method with a different order for the two parameters: <placeholder-2/> The <literal>{c_param_name}</literal> following the method parameter names tells <command>gmmproc</command> to map the C++ parameter to the specified C parameter within the <literal>{}</literal>. Since the C++ parameter names correspond to the C ones, the above could be re-written as: <placeholder-3/>For any of the <classname>RecentChooser</classname> classes, if you don't wish to display all of the items in the list of recent files, you can filter the list to show only those that you want. You can filter the list with the help of the <classname>RecentFilter</classname> class. This class allows you to filter recent files by their name (<methodname>add_pattern()</methodname>), their mime type (<methodname>add_mime_type()</methodname>), the application that registered them (<methodname>add_application()</methodname>), or by a custom filter function (<methodname>add_custom()</methodname>). It also provides the ability to filter based on how long ago the file was modified and which groups it belongs to.For each page that needs to be rendered, the following signals are emitted: <placeholder-1/>For example, for <classname>Pango::Analysis</classname> in <filename>item.hg</filename>: <placeholder-1/>For example, from <filename>icontheme.hg</filename>: <placeholder-1/>For example, if there was a C function that returned a <type>GtkWidget*</type> and for some reason, instead of having the C++ method also return the widget, it was desirable to have the C++ method place the widget in a specified output parameter, an initialization macro such as the following would be necessary: <placeholder-1/>For example, in <filename>rectangle.hg</filename>: <placeholder-1/>For example, in Pangomm, <filename>layoutline.hg</filename>: <placeholder-1/>For information about implementing your own signals rather than just connecting to the existing <application>gtkmm</application> signals, see the <link linkend="chapter-custom-signals">appendix</link>.For instance,For instance, <application>gedit</application> can supply and receive the <literal>"UTF8_STRING"</literal> target, so you can paste data into <application>gedit</application> from any application that supplies that target. Or two different image editing applications might supply and receive a variety of image formats as targets. As long as one application can receive one of the targets that the other supplies then you will be able to copy data from one to the other.For instance, <placeholder-1/>For instance, for <classname>Gdk::Rectangle</classname>: <placeholder-1/>For instance, for <classname>Pango::AttrIter</classname>: <placeholder-1/>For instance, for <classname>Pango::Coverage</classname>: <placeholder-1/>For instance, for a CellRendererText, you would set the cell's <emphasis>editable</emphasis> property to true, like so:For instance, from <classname>Gdk::RGBA</classname>: <placeholder-1/>For instance, from <classname>Glib::Checksum</classname>: <placeholder-1/>For instance, from <filename>accelgroup.hg</filename>: <placeholder-1/>For instance, from <filename>button.hg</filename>: <placeholder-1/>For instance, from <filename>buttonbox.hg</filename>: <placeholder-1/>For instance, from <filename>celleditable.hg</filename>: <placeholder-1/>For instance, from <filename>container.hg</filename>: <placeholder-1/>For instance, from <filename>entry.hg</filename>: <placeholder-1/>For instance, from <filename>enums.hg</filename>: <placeholder-1/>For instance, from <filename>pixbuf.hg</filename>: <placeholder-1/>For instance, from <filename>widget.hg</filename>: <placeholder-1/>For instance, let's pretend that we are wrapping a C library called libsomething. It provides a <classname>GObject</classname>-based API with types named, for instance, <classname>SomeWidget</classname> and <classname>SomeStuff</classname>.For instance, this code would be problematic:For instance, to create a signal that sends 2 parameters, a <type>bool</type> and an <type>int</type>, just declare a <classname>sigc::signal</classname>, like so: <placeholder-1/>For instance:For more detailed information about signals, see the <link linkend="chapter-signals">appendix</link>.For multiple-selection, you need to define a callback, and give it to <methodname>selected_foreach()</methodname>, <methodname>selected_foreach_path()</methodname>, or <methodname>selected_foreach_iter()</methodname>, like so:For reference, it is possible to generate a file which contains all strings which appear in your code, even if they are not marked for translation, together with file name and line number references. To generate such a file named <literal>my-strings</literal>, execute the following command, within the source code directory: <placeholder-1/>For single-selection, you can just call <methodname>get_selected()</methodname>, like so:For the input of passwords, passphrases and other information you don't want echoed on the screen, calling <methodname>set_visibility()</methodname> with <literal>false</literal> will cause the text to be hidden.FrameFrames can enclose one or a group of widgets within a box, optionally with a title. For instance, you might place a group of <classname>RadioButton</classname>s or <classname>CheckButton</classname>s in a <classname>Frame</classname>.From time to time, it may be useful to be able to embed a widget from another application within your application. <application>gtkmm</application> allows you to do this with the <classname>Gtk::Socket</classname> and <classname>Gtk::Plug</classname> classes. It is not anticipated that very many applications will need this functionality, but in the rare case that you need to display a widget that is running in a completely different process, these classes can be very helpful.Full ExampleFunction scope widgetsGTK+ 3.0GTK+ and <application>gtkmm</application> were designed to work well with Microsoft Windows, and the developers encourage its use on the win32 platform. However, Windows has no standard installation system for development libraries. Please see the <ulink url="http://live.gnome.org/gtkmm/MSWindows">Windows Installation</ulink> page for Windows-specific installation instructions and notes.GTK+ uses the <ulink url="http://cairographics.org">Cairo</ulink> drawing API. With <application>gtkmm</application>, you may use the <ulink url="http://www.cairographics.org/cairomm/">cairomm</ulink> C++ API for cairo.Generate a declaration of the <function>on_something()</function> virtual method in the <filename>.h</filename> file, but do not generate a definition in the <filename>.cc</filename> file. Use this when you must generate the definition by hand.Generating the .defs files.Generating the enums .defsGenerating the methods .defsGenerating the signals and properties .defsGeneration of the source code for a gtkmm-style wrapper API requires use of tools such as <command>gmmproc</command> and <filename>generate_wrap_init.pl</filename>. In theory you could write your own build files to use these appropriately, but a much better option is to make use of the build infrastructure provided by the mm-common module. To get started, it helps a lot to pick an existing binding module as an example to look at.Get the data from the widgets in the <literal>custom_widget_apply</literal> signal handler.Getting help with translationsGetting valuesGive all command-line options to <methodname>Gtk::Application::create()</methodname> and add the flag <literal>Gio::APPLICATION_HANDLES_COMMAND_LINE</literal>. Connect a signal handler to the <literal>command_line</literal> signal, and handle the command-line options in the signal handler.Glade and Gtk::BuilderGlib::IO_ERR - Call your method when an error has occurred on the file descriptor.Glib::IO_HUP - Call your method when hung up (the connection has been broken usually for pipes and sockets).Glib::IO_IN - Call your method when there is data ready for reading on your file descriptor.Glib::IO_OUT - Call your method when the file descriptor is ready for writing.Glib::IO_PRI - Call your method when the file descriptor has urgent data to be read.Glib::RefPtr&lt;Gtk::Adjustment&gt; Gtk::Adjustment::create(
  double value,
  double lower,
  double upper,
  double step_increment = 1,
  double page_increment = 10,
  double page_size = 0);Glib::RefPtr&lt;Gtk::Application&gt; app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base");Glib::RefPtr&lt;Gtk::Clipboard&gt; refClipboard = Gtk::Clipboard::get();

//Targets:
std::vector&lt;Gtk::TargetEntry&gt; targets;
targets.push_back( Gtk::TargetEntry("example_custom_target") );
targets.push_back( Gtk::TargetEntry("UTF8_STRING") );

refClipboard-&gt;set( targets,
    sigc::mem_fun(*this, &amp;ExampleWindow::on_clipboard_get),
    sigc::mem_fun(*this, &amp;ExampleWindow::on_clipboard_clear) );Glib::RefPtr&lt;Gtk::ListStore&gt; refListStore =
    Gtk::ListStore::create(m_Columns);Glib::RefPtr&lt;Gtk::RecentInfo&gt; info;
try
{
  info = recent_manager-&gt;lookup_item(uri);
}
catch(const Gtk::RecentManagerError&amp; ex)
{
  std::cerr &lt;&lt; "RecentManagerError: " &lt;&lt; ex.what() &lt;&lt; std::endl;
}
if (info)
{
  // item was found
}Glib::RefPtr&lt;Gtk::RecentManager&gt; recent_manager = Gtk::RecentManager::get_default();
recent_manager-&gt;add_item(uri);Glib::RefPtr&lt;Gtk::TextBuffer::Mark&gt; refMark =
    refBuffer-&gt;create_mark(iter);Glib::RefPtr&lt;Gtk::TextBuffer::Tag&gt; refTagMatch =
    Gtk::TextBuffer::Tag::create();
refTagMatch-&gt;property_background() = "orange";Glib::RefPtr&lt;Gtk::TextBuffer::TagTable&gt; refTagTable =
    Gtk::TextBuffer::TagTable::create();
refTagTable-&gt;add(refTagMatch);
//Hopefully a future version of <application>gtkmm</application> will have a set_tag_table() method,
//for use after creation of the buffer.
Glib::RefPtr&lt;Gtk::TextBuffer&gt; refBuffer =
    Gtk::TextBuffer::create(refTagTable);Glib::RefPtr&lt;Gtk::TextChildAnchor&gt; refAnchor =
    refBuffer-&gt;create_child_anchor(iter);Glib::RefPtr&lt;Gtk::TreeModelSort&gt; sorted_model =
    Gtk::TreeModelSort::create(model);
sorted_model-&gt;set_sort_column(columns.m_col_name, Gtk::SORT_ASCENDING);
treeview.set_model(sorted_model);Glib::RefPtr&lt;Gtk::TreeSelection&gt; refTreeSelection =
    m_TreeView.get_selection();Glib::RefPtr&lt;Gtk::UIManager&gt; m_refUIManager =
    Gtk::UIManager::create();
m_refUIManager-&gt;insert_action_group(m_refActionGroup);
add_accel_group(m_refUIManager-&gt;get_accel_group());Glib::ustringGlib::ustring and std::iostreamsGlib::ustring strText = row[m_Columns.m_col_text];
int number = row[m_Columns.m_col_number];Glib::ustring ui_info =
    "&lt;ui&gt;"
    "  &lt;menubar name='MenuBar'&gt;"
    "    &lt;menu action='MenuFile'&gt;"
    "      &lt;menuitem action='New'/&gt;"
    "      &lt;menuitem action='Open'/&gt;"
    "      &lt;separator/&gt;"
    "      &lt;menuitem action='Quit'/&gt;"
    "    &lt;/menu&gt;"
    "    &lt;menu action='MenuEdit'&gt;"
    "      &lt;menuitem action='Cut'/&gt;"
    "      &lt;menuitem action='Copy'/&gt;"
    "      &lt;menuitem action='Paste'/&gt;"
    "    &lt;/menu&gt;"
    "  &lt;/menubar&gt;"
    "  &lt;toolbar  name='ToolBar'&gt;"
    "    &lt;toolitem action='Open'/&gt;"
    "    &lt;toolitem action='Quit'/&gt;"
    "  &lt;/toolbar&gt;"
    "&lt;/ui&gt;";

m_refUIManager-&gt;add_ui_from_string(ui_info);Glib::ustring ui_info =
    "&lt;ui&gt;"
    "  &lt;popup name='PopupMenu'&gt;"
    "    &lt;menuitem action='ContextEdit'/&gt;"
    "    &lt;menuitem action='ContextProcess'/&gt;"
    "    &lt;menuitem action='ContextRemove'/&gt;"
    "  &lt;/popup&gt;"
    "&lt;/ui&gt;";

m_refUIManager-&gt;add_ui_from_string(ui_info);GridGroupsGtk::Alignment
Gtk::Arrow
Gtk::AspectFrame
Gtk::Bin
Gtk::Box
Gtk::Button
Gtk::CheckButton
Gtk::Fixed
Gtk::Frame
Gtk::Grid
Gtk::Image
Gtk::Label
Gtk::MenuItem
Gtk::Notebook
Gtk::Paned
Gtk::RadioButton
Gtk::Range
Gtk::ScrolledWindow
Gtk::Separator
Gtk::Table (deprecated from <application>gtkmm</application> version 3.4)
Gtk::ToolbarGtk::Application and command-line optionsGtk::Box(Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL, int spacing = 0);
void set_spacing(int spacing);
void set_homogeneous(bool homogeneous = true);Gtk::Button* pButton = new Gtk::Button("_Something", true);Gtk::CellRendererToggle* pRenderer =
    Gtk::manage( new Gtk::CellRendererToggle() );
pRenderer-&gt;signal_toggled().connect(
    sigc::bind( sigc::mem_fun(*this,
        &amp;Example_TreeView_TreeStore::on_cell_toggled), m_columns.dave)
);Gtk::ComboBox now derives from CellLayout, allowing easier layout and alignment of its <classname>Gtk::CellRenderer</classname>s.Gtk::DrawingArea myArea;
Cairo::RefPtr&lt;Cairo::Context&gt; myContext = myArea.get_window()-&gt;create_cairo_context();
myContext-&gt;set_source_rgb(1.0, 0.0, 0.0);
myContext-&gt;set_line_width(2.0);Gtk::Entry* entry = m_Combo.get_entry();
if (entry)
{
  // The Entry shall receive focus-out events.
  entry-&gt;add_events(Gdk::FOCUS_CHANGE_MASK);

  // Alternatively you can connect to m_Combo.signal_changed().
  entry-&gt;signal_changed().connect(sigc::mem_fun(*this,
    &amp;ExampleWindow::on_entry_changed) );

  entry-&gt;signal_activate().connect(sigc::mem_fun(*this,
    &amp;ExampleWindow::on_entry_activate) );

  entry-&gt;signal_focus_out_event().connect(sigc::mem_fun(*this,
    &amp;ExampleWindow::on_entry_focus_out_event) );
}Gtk::EventBox();Gtk::Label support some simple formatting, for instance allowing you to make some text bold, colored, or larger. You can do this by providing a string to <methodname>set_markup()</methodname>, using the <ulink url="http://developer.gnome.org/pango/unstable/PangoMarkupFormat.html">Pango Markup syntax</ulink>. For instance, <code> &lt;b&gt;bold text&lt;/b&gt; and &lt;s&gt;strikethrough text&lt;/s&gt; </code> .Gtk::TreeModel::Children children = row.children();Gtk::TreeModel::Row row = *iter;Gtk::TreeModel::Row row = m_refModel-&gt;children()[5]; //The fifth row.
if(row)
  refTreeSelection-&gt;select(row);Gtk::TreeModel::iterator iter = m_Combo.get_active();
if(iter)
{
  Gtk::TreeModel::Row row = *iter;

  //Get the data for the selected row, using our knowledge
  //of the tree model:
  int id = row[m_Columns.m_col_id];
  set_something_id_chosen(id); //Your own function.
}
else
  set_nothing_chosen(); //Your own function.Gtk::TreeModel::iterator iter = m_refListStore-&gt;append();Gtk::TreeModel::iterator iter = m_refModel-&gt;children().begin()
if(iter)
  refTreeSelection-&gt;select(iter);Gtk::TreeModel::iterator iter_child =
    m_refTreeStore-&gt;append(row.children());Gtk::TreeView::Column* pColumn =
  Gtk::manage(new Gtk::TreeView::Column("Icon Name"));

// m_columns.icon and m_columns.iconname are columns in the model.
// pColumn is the column in the TreeView:
pColumn-&gt;pack_start(m_columns.icon, /* expand= */ false);
pColumn-&gt;pack_start(m_columns.iconname);

m_TreeView.append_column(*pColumn);Gtk::TreeView::Column* pColumn = treeview.get_column(0);
if(pColumn)
  pColumn-&gt;set_sort_column(m_columns.m_col_id);Gtk::Widget* pMenubar = m_refUIManager-&gt;get_widget("/MenuBar");
pBox-&gt;add(*pMenuBar, Gtk::PACK_SHRINK);Gtk::Window window;
window.set_default_size(200, 200);Hand-coded source filesHand-coding constructorsHandle the options in <function>main()</function> and hide them from <classname>Gtk::Application</classname> by setting <literal>argc = 1</literal> in the call to <methodname>Gtk::Application::create()</methodname>.Handling <literal>button_press_event</literal>Handling an X event doesn't affect the Widget's other signals. If you handle <literal>button_press_event</literal> for <classname>Gtk::Button</classname>, you'll still be able to get the <literal>clicked</literal> signal. They are emitted at (nearly) the same time.Headers and LinkingHello WorldHello World 2Hello World in <application>gtkmm</application>HelloWorld::HelloWorld()
:
  m_button ("Hello World")
{
  set_border_width(10);
  m_button.signal_clicked().connect(sigc::mem_fun(*this,
    &amp;HelloWorld::on_button_clicked));
  add(m_button);.
  m_button.show();
}Here are some examples of normal C++ memory management:Here is a list of some of these Widgets:Here is a simple example that packs 100 toggle buttons into a ScrolledWindow. Try resizing the window to see the scrollbars react.Here is a small bit of code to tie it all together: (Note that usually you wouldn't load the image every time in the draw signal handler! It's just shown here to keep it all together.)Here is a very simple example, demonstrating a drag and drop <literal>Copy</literal> operation:Here is an example callback method:Here is an example of a program that draws some text, some of it upside-down. The Printing chapter contains another <link linkend="sec-printing-example">example</link> of drawing text.Here is an example of a simple program that draws an image.Here is an excerpt from a <application>gdb</application> session. Only the most interesting parts of the output are shown. <placeholder-1/> You can see that the exception was thrown from <filename>without_signal.cc</filename>, line 6 (<code>throw "Something";</code>).Here is some example code from <filename>gtkmm/demos/gtk-demo/example_icontheme.cc</filename>, which has a pixbuf icon and a text name in the same column:Here is the source code for the example that produced the screenshots above. When you run this example, provide a number between 1 and 3 as a command-line option, to see different packing options in use.Here we define a new class called <classname>OverriddenButton</classname>, which inherits from <classname>Gtk::Button</classname>. The only thing we change is the <methodname>on_clicked()</methodname> method, which is called whenever <classname>Gtk::Button</classname> emits the <literal>clicked</literal> signal. This method prints "Hello World" to <literal>stdout</literal>, and then calls the original, overridden method, to let <classname>Gtk::Button</classname> do what it would have done had we not overridden.Here's a simple example: <placeholder-1/>Here's a slightly larger example of slots in action:Here's an example of a <classname>SpinButton</classname> in action:Here's an example of a signal handler being connected to a signal:Here's an example of a simple program that draws an arc, a circle and an ellipse into a drawing area.Here's an example of this technique:Here's the constructor for the <classname>Box</classname> widget, and methods that set per-container packing options: <placeholder-1/> Passing <literal>true</literal> to <methodname>set_homogeneous()</methodname> will cause all of the contained widgets to be the same size. <parameter>spacing</parameter> is a (minimum) number of pixels to leave between each widget.How gettext worksHow to use Git for GNOME translatorsHowever, <application>Glib</application> defines <function>gettext()</function> support macros which are shorter wrappers in an easy-to-use form. To use these macros, include <literal>&lt;glibmm/i18n.h&gt;</literal>, and then, for example, substitute: <placeholder-1/> with: <placeholder-2/>However, care is required when writing programs based on <application>gtkmm</application> using multiple threads of execution, arising from the fact that <application>libsigc++</application>, and in particular <classname>sigc::trackable</classname>, are not thread-safe. That's because none of the complex interactions that occur behind the scenes when using <application>libsigc++</application> are protected by a mutex or other means of synchronization. <placeholder-1/>However, this does not allow you any control of which items can be dragged, and where they can be dropped. If you need that extra control then you might create a derived <literal>Gtk::TreeModel</literal> from <literal>Gtk::TreeStore</literal> or <literal>Gtk::ListStore</literal> and override the <literal>Gtk::TreeDragSource::row_draggable()</literal> and <literal>Gdk::TreeDragDest::row_drop_possible()</literal> virtual methods. You can examine the <literal>Gtk::TreeModel::Path</literal>s provided and allow or disallow dragging or dropping by returning <literal>true</literal> or <literal>false</literal>.However, this is even simpler when using the <function>PKG_CHECK_MODULES()</function> macro in a standard configure.ac file with autoconf and automake. For instance: <placeholder-1/> This checks for the presence of gtkmm and defines MYAPP_LIBS and MYAPP_CFLAGS for use in your Makefile.am files.However, you might not want the new values to be stored immediately. For instance, maybe you want to restrict the input to certain characters or ranges of values.However, you probably already avoid bare char* arrays and pointer arithmetic by using <classname>std::string</classname>, so you just need to start using <classname>Glib::ustring</classname> instead. See the <link linkend="sec-basics-ustring">Basics</link> chapter about <classname>Glib::ustring</classname>.I've been embedded.
A plug was addedINTLTOOL_FILES = intltool-extract.in \
                 intltool-merge.in \
                 intltool-update.inIT_PROG_INTLTOOL([0.35.0])

GETTEXT_PACKAGE=programname
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"],
                   [The domain to use with gettext])
AM_GLIB_GNU_GETTEXT

PROGRAMNAME_LOCALEDIR=[${datadir}/locale]
AC_SUBST(PROGRAMNAME_LOCALEDIR)IdealIdeally, we would like you to <ulink url="http://www.gtkmm.org/bugs.shtml">provide a patch</ulink> to the <filename>docs/tutorial/C/gtkmm-tutorial-in.xml</filename> file. This file is currently in the <literal>gtkmm-documentation</literal> module in GNOME git.Idle FunctionsIf a particular class object derives from <classname>sigc::trackable</classname>, only one thread should create <classname>sigc::slot</classname> objects representing any of the class's non-static methods by calling <function>sigc::mem_fun()</function>. The first thread to create such a slot should be regarded as owning the relevant object for the purpose of creating further slots referencing <emphasis>any</emphasis> of its non-static methods using that function, or nulling those slots by disconnecting them or destroying the trackable object.If a programmer does not need a class scope widget, a function scope widget may also be used. The advantages to function scope over class scope are the increased data hiding and reduced dependencies. <placeholder-1/>If a programmer does not need dynamic memory allocation, automatic widgets in class scope may be used. One advantage of automatic widgets in class scope is that memory management is grouped in one place. The programmer does not risk memory leaks from failing to <literal>delete</literal> a widget.If everything worked correctly, you should be able to build <application>gtkmm</application> and all of its dependencies from git by executing <command>jhbuild build</command> (or, if you didn't specify <application>gtkmm</application> in the <varname>modules</varname> variable, with the command <command>jhbuild build gtkmm</command>).If for some reason the <classname>Socket</classname> couldn't attach the <classname>Plug</classname>, the window would look something like this:If the enum is not a <classname>GType</classname>, you must pass a third parameter NO_GTYPE. This is the case when there is no <function>*_get_type()</function> function for the C enum, but be careful that you don't just need to include an extra header for that function. You should also file a bug against the C API, because all enums should be registered as GTypes.If there are many caught exceptions before the interesting uncaught one, this method can be tedious. It can be automated with the following <application>gdb</application> commands. <placeholder-1/> These commands will print a backtrace from each <code>throw</code> and continue. The backtrace from the last (or possibly the last but one) <code>throw</code> before the program stops, is the interesting one.If this is the first time you're using a program that uses the Recent Files framework, the dialog may be empty at first. Otherwise it should show the list of recently used documents registered by other applications.If you are interested in helping out with the development of <application>gtkmm</application>, or fixing a bug in <application>gtkmm</application>, you'll probably need to build the development version of <application>gtkmm</application>. However, you should not install a development version over your stable version. Instead, you should install it alongside your existing <application>gtkmm</application> installation, in a separate path.If you are using <application>gettext</application> directly, you can only mark strings for translation if they are in source code file. However, if you use <application>intltool</application>, you can mark strings for translation in a variety of other file formats, including <application>Glade</application> UI files, xml, <ulink url="http://standards.freedesktop.org/desktop-entry-spec/latest/">.desktop files</ulink> and several more. So, if you have designed some of the application UI in <application>Glade</application> then also add your <filename>.glade</filename> files to the list in <literal>POTFILES.in</literal>.If you call <methodname>Gtk::TreeView::set_reorderable()</methodname> then your TreeView's items can be moved within the treeview itself. This is demonstrated in the <classname>TreeStore</classname> example.If you copied the skeleton source tree in mm-common and substituted the placeholder text, then you will already have suitable <filename>Makefile.am</filename> and <filename>Doxyfile.in</filename> files. With the mm-common build setup, the list of Doxygen input files is not defined in the Doxygen configuration file, but passed along from <command>make</command> to the standard input of <command>doxygen</command>. The input file list is defined by the <varname>doc_input</varname> variable in the <filename>Makefile.am</filename> file.If you copy a <classname>RefPtr</classname>, for instance <placeholder-1/> , or if you pass it as a method argument or a return type, then <classname>RefPtr</classname> will do any necessary referencing to ensure that the instance will not be destroyed until the last <classname>RefPtr</classname> has gone out of scope.If you do decide to contribute, please post your contribution to the <application>gtkmm</application> mailing list at <ulink url="mailto:gtkmm-list@gnome.org">&lt;gtkmm-list@gnome.org&gt;</ulink>. Also, be aware that the entirety of this document is free, and any addition you provide must also be free. That is, people must be able to use any portion of your examples in their programs, and copies of this document (including your contribution) may be distributed freely.If you don't want to look for a specific URI, but instead want to get a list of all recently used items, <classname>RecentManager</classname> provides the <methodname>get_items()</methodname> function. The return value of this function is a <classname>std::vector</classname> of all recently used files. The following code demonstrates how you might get a list of recently used files:If you have created a <classname>Tag</classname> and added it to the <classname>TagTable</classname>, you may apply that tag to part of the <classname>TextBuffer</classname> so that some of the text is displayed with that formatting. You define the start and end of the range of text by specifying <classname>Gtk::TextBuffer::iterator</classname>s. For instance:If you pass <literal>true</literal> to the <methodname>set_activates_default()</methodname> method, pressing Enter in the <classname>Gtk::Entry</classname> will activate the default widget for the window containing the <classname>Gtk::Entry</classname>. This is especially useful in dialog boxes. The default widget is usually one of the dialog buttons, which e.g. will close the dialog box. To set a widget as the default widget, use <methodname>Gtk::Widget::set_can_default()</methodname> and <methodname>Gtk::Widget::grab_default()</methodname>.If you share an adjustment object between a Scrollbar and a TextView widget, manipulating the scrollbar will automagically adjust the TextView widget. You can set it up like this:If you try to draw one pixel wide lines, you may notice that the line sometimes comes up blurred and wider than it ought to be. This happens because Cairo will try to draw from the selected position, to both sides (half to each), so if you're positioned right on the intersection of the pixels, and want a one pixel wide line, Cairo will try to use half of each adjacent pixel, which isn't possible (a pixel is the smallest unit possible). This happens when the width of the line is an odd number of pixels (not just one pixel).If you use one signal handler to catch the same signal from several widgets, you might like that signal handler to receive some extra information. For instance, you might want to know which button was clicked. You can do this with <function>sigc::bind()</function>. Here's some code from the <link linkend="sec-helloworld2">helloworld2</link> example. <placeholder-1/> This says that we want the signal to send an extra <classname>Glib::ustring</classname> argument to the signal handler, and that the value of that argument should be "button 1". Of course we will need to add that extra argument to the declaration of our signal handler: <placeholder-2/> Of course, a normal "clicked" signal handler would have no arguments.If you want to help develop <application>gtkmm</application> or experiment with new features, you can also install <application>gtkmm</application> from git. Most users will never need to do this, but if you're interested in helping with <application>gtkmm</application> development, see the <link linkend="chapter-working-with-source">Working with gtkmm's Source Code</link> appendix.If you want to register a file with metadata, you can pass a <classname>RecentManager::Data</classname> parameter to <methodname>add_item()</methodname>. The metadata that can be set on a particular file item is as follows:If you want to specify a method that gets called when nothing else is happening, use the following:If you wish to learn more about smartpointers, you might look in these books: <placeholder-1/>If you've drawn a series of lines that form a path, you may want them to join together in a certain way. Cairo offers three different ways to join lines together: Miter, Bevel, and Round. These are show below:If you've never used a packing toolkit before, it can take some getting used to. You'll probably find, however, that you don't need to rely on visual form editors quite as much as you might with other toolkits.If your distribution does not provide a pre-built <application>gtkmm</application> package, or if you want to install a different version than the one provided by your distribution, you can also install <application>gtkmm</application> from source. The source code for <application>gtkmm</application> can be downloaded from <ulink url="http://www.gtkmm.org/"/>.If your program is free software, there is a whole <literal>GNOME</literal> subproject devoted to helping you make translations, the <ulink url="https://live.gnome.org/TranslationProject/"><literal>GNOME</literal> Translation Project</ulink>.Implementing custom logic for editable cells.In <filename>configure.ac</filename>, <placeholder-1/>In <filename>skeleton/skeletonmm/Makefile.am</filename> we must mention the correct values for the generic variables that are used elsewhere in the build system:In <filename>skeleton/src/Makefile.am</filename> we must mention the correct values for the generic variables that are used elsewhere in the build system:In addition to adding items to the list, you can also look up items from the list and modify or remove items.In addition to changing a file's URI, you can also remove items from the list, either one at a time or by clearing them all at once. The former is accomplished with <methodname>remove_item()</methodname>, the latter with <methodname>purge_items()</methodname>.In addition to drawing basic straight lines, there are a number of things that you can customize about a line. You've already seen examples of setting a line's color and width, but there are others as well.In addition to drawing straight lines Cairo allows you to easily draw curved lines (technically a cubic Bézier spline) using the <methodname>Cairo::Context::curve_to()</methodname> and <methodname>Cairo::Context::rel_curve_to()</methodname> functions. These functions take coordinates for a destination point as well as coordinates for two 'control' points. This is best explained using an example, so let's dive in.In general, gtkmm-style projects use Doxygen, which reads specially formatted C++ comments and generates HTML documentation. You may write these doxygen comments directly in the header files.In the <classname>Gtk::Window</classname>, we have also the default handler overridden (<methodname>on_key_release_event()</methodname>), and another handler being called before the default handler (<methodname>windowKeyReleaseBefore()</methodname>).In the <link linkend="sec-wrapping-hg-files">.hg and .ccg files</link> section you can learn about the syntax used in these files.In the example above we drew everything using absolute coordinates. You can also draw using relative coordinates. For a straight line, this is done with the function <methodname>Cairo::Context::rel_line_to()</methodname>.In the instructions below we will assume that you will not be using <application>gettext</application> directly, but <application>intltool</application>, which was written specifically for <literal>GNOME</literal>. <application>intltool</application> uses <function>gettext()</function>, which extracts strings from source code, but <application>intltool</application> can also combine strings from other files, for example from desktop menu details, and GUI resource files such as <application>Glade</application> files, into standard <application>gettext</application><filename>.pot/.po</filename> files.In the top-level Makefile.am: <placeholder-1/>In these cases, you should add extra characters to the strings. For instance, use <literal>"jumps[noun]"</literal> and <literal>"jumps[verb]"</literal> instead of just <literal>"jumps"</literal> and strip them again outside the <function>gettext</function> call. If you add extra characters you should also add a comment for the translators before the <function>gettext</function> call. Such comments will be shown in the <filename>.po</filename> files. For instance:In this example there are three event handlers that are called after <classname>Gtk::Window</classname>'s default event handler, one in the <classname>Gtk::Entry</classname>, one in the <classname>Gtk::Grid</classname> and one in the <classname>Gtk::Window</classname>.In this example there are three keyboard shortcuts: <keycap>Alt</keycap>+<keycap>1</keycap> selects the first radio button, <keycap>Alt</keycap>+<keycap>2</keycap> selects the second one, and the <keycap>Esc</keycap> key hides (closes) the window. The default event signal handler is overridden, as described in the <link linkend="sec-overriding-default-signal-handlers">Overriding default signal handlers</link> section in the appendix.In this example, we'll construct a small but fully functional <application>gtkmm</application> program and draw some lines into the window. The lines are drawn by creating a path and then stroking it. A path is created using the functions <methodname>Cairo::Context::move_to()</methodname> and <methodname>Cairo::Context::line_to()</methodname>. The function <methodname>move_to()</methodname> is similar to the act of lifting your pen off of the paper and placing it somewhere else -- no line is drawn between the point you were at and the point you moved to. To draw a line between two points, use the <methodname>line_to()</methodname> function.In this section of the tutorial, we'll cover the basic Cairo drawing model, describe each of the basic drawing elements in some detail (with examples), and then present a simple application that uses Cairo to draw a custom clock widget.In your <literal>src/Makefile.am</literal>, update your <literal>AM_CPPFLAGS</literal> to add the following preprocessor macro definition:In your callback, compare the vector of available targets with those that your application supports for pasting. You could enable or disable a Paste menu item, depending on whether pasting is currently possible. For instance:In your signal handler, you should examine the new value and then store it in the Model if that is appropriate for your application.Includes the other files.Independently sorted views of the same modelInfoBarInheritance can be used to derive new widgets. The derivation of new widgets in GTK+ C code is so complicated and error prone that almost no C coders do it. As a C++ developer you know that derivation is an essential Object Orientated technique.InitializationInstallationInstalling <application>gtkmm</application> with <application>jhbuild</application>Installing From SourceInstalling and Using the git version of <application>gtkmm</application>Instead of laboriously connecting signal handlers to signals, you can simply make a new class which inherits from a widget - say, a Button - and then override the default signal handler, such as Button::on_clicked(). This can be a lot simpler than hooking up signal handlers for everything.Intermediate typesInternationalization and LocalizationInternationalizing GNOME applicationsIntltool READMEIntroductionIt also takes an optional extra argument: <placeholder-1/>It follows the same form. The number 3 at the end of the type's name indicates that our signal handler will need three arguments. The first type in the type list is <type>void</type>, so that should be our signal handler's return type. The following three types are the argument types, in order. Our signal handler's prototype could look like this:It is common for binding modules to track the version number of the library they are wrapping. So, for instance, if the C library is at version 1.23.4, then the initial version of the binding module would be 1.23.0. However, avoid starting with an even minor version number as that usually indicates a stable release.It is good practice to put all modifications to the graphics state between <methodname>save()</methodname>/<methodname>restore()</methodname> function calls. For example, if you have a function that takes a <classname>Cairo::Context</classname> reference as an argument, you might implement it as follows:It supports pasting of 2 targets - both the custom one and a text one that creates an arbitrary text representation of the custom data.It uses <methodname>request_targets()</methodname> and the <literal>owner_change</literal> signal and disables the Paste button if it can't use anything on the clipboard.It's impossible to predict the amount of space necessary for text after it has been translated to other languages, or displayed in a different font. On Unix it is also impossible to anticipate the effects of every theme and window manager.It's possible that certain strings will be marked as <literal>fuzzy</literal> in the <filename>.po</filename> file. These translations will not substitute the original string. To make them appear, simply remove the <literal>fuzzy</literal> tag.Iterating over Model RowsIteratorsJonathonJongsmaJust call the non-const version of the same function, instead of generating almost duplicate code.Just like normal pointers, you can check whether a <classname>RefPtr</classname> points to anything.Keyboard EventsKeyboard Events - Event PropagationKeyboard Events - SimpleKingKjellLabelLabels are the main method of placing non-editable text in windows, for instance to place a title next to a <classname>Entry</classname> widget. You can specify the text in the constructor, or later with the <methodname>set_text()</methodname> or <methodname>set_markup()</methodname> methods.Lack of propertiesLaursenLess C++ code is required.Let's look at an example of overriding:Let's take a look at a slightly improved <literal>helloworld</literal>, showing what we've learnt.Let's take another look at a Signal's <literal>connect</literal> method:Like checkboxes, radio buttons also inherit from <classname>Gtk::ToggleButton</classname>, but these work in groups, and only one RadioButton in a group can be selected at any one time.Like the <classname>TreeView</classname>, you should probably put your <classname>TextView</classname> inside a <classname>ScrolledWindow</classname> to allow the user to see and move around the whole text area with scrollbars.Likewise, replace all instances of <varname>Joe Hacker</varname> by the name of the intended copyright holder, which is probably you. Do the same for the <varname>joe@example.com</varname> email address.Line ends can have different styles as well. The default style is for the line to start and stop exactly at the destination points of the line. This is called a Butt cap. The other options are Round (uses a round ending, with the center of the circle at the end point) or Square (uses a squared ending, with the center of the square at the end point). This setting is set using the function <methodname>Cairo::Context::set_line_cap()</methodname>.Line stylesListStoreListStore, for rowsLoading the .glade fileLooking up Items in the List of Recent FilesLots of people need to implement right-click context menus for <classname>TreeView</classname>'s so we will explain how to do that here to save you some time. Apart from one or two points, it's much the same as a normal context menu, as described in the <link linkend="sec-menus-popup">menus chapter</link>.Main MenuMain Menu exampleMakefile.am filesManaged WidgetsMany Cairo drawing functions have a <methodname>_preserve()</methodname> variant. Normally drawing functions such as <methodname>clip()</methodname>, <methodname>fill()</methodname>, or <methodname>stroke()</methodname> will clear the current path. If you use the <methodname>_preserve()</methodname> variant, the current path will be retained so that you can use the same path with the next drawing function.Many GUI toolkits require you to precisely place widgets in a window, using absolute positioning, often using a visual editor. This leads to several problems:Marking strings for translationMarkoMarksMaybe the user should not be able to select every item in your list or tree. For instance, in the gtk-demo, you can select a demo to see the source code, but it doesn't make any sense to select a demo category.Member instances can be used, simplifying memory management. All GTK+ C widgets are dealt with by use of pointers. As a C++ coder you know that pointers should be avoided where possible.Memory managementMenus and ToolbarsMessageDialogMethod macrosMethodsMicrosoft WindowsMiscellaneous WidgetsMixing C and C++ APIsModel ColumnsModelColumns()
{ add(m_col_id); add(m_col_name); }

  Gtk::TreeModelColumn&lt;int&gt; m_col_id;
  Gtk::TreeModelColumn&lt;Glib::ustring&gt; m_col_name;
};

ModelColumns m_columns;Modifying build filesModifying the List of Recent FilesMonitoring I/OMore information about what lies behind the internationalization and localization process is presented and demonstrated in: <placeholder-1/>More than one Model Column per View ColumnMost applications will have only one <classname>Window</classname>, or only one main window. These applications can use the <methodname>Gtk::Application::run(Gtk::Window&amp;)</methodname> overload. It shows the window and returns when the window has been hidden. This might happen when the user closes the window, or when your code decides to <methodname>hide()</methodname> the window. You can prevent the user from closing the window (for instance, if there are unsaved changes) by overriding <methodname>Gtk::Window::on_delete_event()</methodname>.Most custom widgets need their own <classname>Gdk::Window</classname> to draw on. Then you can call <methodname>Gtk::Widget::set_has_window(true)</methodname> in your constructor. (This is the default value.) If you do not call <methodname>set_has_window(false)</methodname>, you must override <methodname>on_realize()</methodname> and call <methodname>Gtk::Widget::set_realized()</methodname> and <methodname>Gtk::Widget::set_window()</methodname> from there.Most dialogs in this chapter are modal, that is, they freeze the rest of the application while they are shown. It's also possible to create a non-modal dialog, which does not freeze other windows in the application. The following example shows a non-modal <classname>AboutDialog</classname>. This is perhaps not the kind of dialog you would normally make non-modal, but non-modal dialogs can be useful in other cases. E.g. <application>gedit</application>'s search-and-replace dialog is non-modal.Most of our examples use this technique.Most of the chapters in this book deal with specific widgets. See the <link linkend="chapter-container-widgets">Container Widgets</link> section for more details about adding widgets to container widgets.Most of the useful member methods for this class are actually in the <classname>Gtk::FileChooser</classname> base class.Most packing uses boxes as in the above example. These are invisible containers into which we can pack our widgets. When packing widgets into a horizontal box, the objects are inserted horizontally from left to right or right to left depending on whether <methodname>pack_start()</methodname> or <methodname>pack_end()</methodname> is used. In a vertical box, widgets are packed from top to bottom or vice versa. You may use any combination of boxes inside or beside other boxes to create the desired effect.MoveMulti-Threaded ProgramMulti-threaded programsMultiple-item widgetsMultiple-item widgets inherit from <classname>Gtk::Container</classname>; just as with <classname>Gtk::Bin</classname>, you use the <methodname>add()</methodname> and <methodname>remove()</methodname> methods to add and remove contained widgets. Unlike <methodname>Gtk::Bin::remove()</methodname>, however, the <methodname>remove()</methodname> method for <classname>Gtk::Container</classname> takes an argument, specifiying which widget to remove.MurrayMurray CummingNext we call the Window's <methodname>set_border_width()</methodname> method. This sets the amount of space between the sides of the window and the widget it contains.Next we make an object of our <classname>HelloWorld</classname> class, whose constructor takes no arguments, but it isn't visible yet. When we call <methodname>Gtk::Application::run()</methodname>, giving it the helloworld Window, it shows the Window and starts the <application>gtkmm</application><emphasis>event loop</emphasis>. During the event loop <application>gtkmm</application> idles, waiting for actions from the user, and responding appropriately. When the user closes the Window, run() will return, causing the final line of our main() function be to executed. The application will then finish.Next we must adapt the various <filename>Makefile.am</filename> files: <placeholder-1/>Next you should create a <classname>UIManager</classname> and add the <classname>ActionGroup</classname> to the <classname>UIManager</classname> with <methodname>insert_action_group()</methodname> At this point is also a good idea to tell the parent window to respond to the specified keyboard shortcuts, by using <methodname>add_accel_group()</methodname>.Next, we use the Window's <methodname>add()</methodname> method to put <literal>m_button</literal> in the Window. (<methodname>add()</methodname> comes from <classname>Gtk::Container</classname>, which is described in the chapter on container widgets.) The <methodname>add()</methodname> method places the Widget in the Window, but it doesn't display the widget. <application>gtkmm</application> widgets are always invisible when you create them - to display them, you must call their <methodname>show()</methodname> method, which is what we do in the next line.Nicolai M. Josuttis, "The C++ Standard Library" - section 4.2Non-modal AboutDialogNormal C++ memory managementNote also that not all widgets receive all X events by default. To receive additional X events, you can use <methodname>Gtk::Widget::set_events()</methodname> before showing the widget, or <methodname>Gtk::Widget::add_events()</methodname> after showing the widget. However, some widgets must first be placed inside an <classname>EventBox</classname> widget. See the <link linkend="chapter-widgets-without-xwindows">Widgets Without X-Windows</link> chapter.Note that UTF-8 isn't compatible with 8-bit encodings like ISO-8859-1. For instance, German umlauts are not in the ASCII range and need more than 1 byte in the UTF-8 encoding. If your code contains 8-bit string literals, you have to convert them to UTF-8 (e.g. the Bavarian greeting "Grüß Gott" would be "Gr\xC3\xBC\xC3\x9F Gott").Note that files ending in <filename>.in</filename> will be used to generate files with the same name but without the <filename>.in</filename> suffix, by replacing some variables with actual values during the configure stage.Note that if you mention extra modules in addition to gtkmm-3.0, they should be separated by spaces, not commas.Note that in this case, we've expressed nearly everything in terms of the height and width of the window, including the width of the lines. Because of this, when you resize the window, everything scales with the window. Also note that there are three drawing sections in the function and each is wrapped with a <methodname>save()</methodname>/<methodname>restore()</methodname> pair so that we're back at a known state after each drawing.Note that most language teams only consist of 1-3 persons, so if your program contains a lot of strings, it might last a while before anyone has the time to look at it. Also, most translators do not want to waste their time (translating is a very time-consuming task) so if they do not assess your project as being really serious (in the sense that it is polished and being maintained) they may decide to spend their time on some other project.Note that the instance (such as m_Columns here) should usually not be static, because it often needs to be instantiated after glibmm has been instantiated.Note that this is where we specify the names of the actions as they will be seen by users in menus and toolbars. Therefore, this is where you should make strings translatable, by putting them inside the _() macro.Note that to build <application>gtkmm</application> from git, you'll often need to build many of its dependencies from git as well. <application>jhbuild</application> makes this easier than it would normally be, but it will take quite a while to build and install them all. You will probably encounter build problems, though these will usually be corrected quickly if you report them.Note that we don't pass a pointer to <methodname>on_button_clicked()</methodname> directly to the signal's <methodname>connect()</methodname> method. Instead, we call <function>sigc::ptr_fun()</function>, and pass the result to <methodname>connect()</methodname>.Note that you can't just do <placeholder-1/> because the group is modified by <methodname>set_group()</methodname> and therefore non-const.Note that you must specify actions for sub menus as well as menu items.Note that, due to GTK+'s theming system, the appearance of these widgets will vary. In the case of checkboxes and radio buttons, they may vary considerably.Note, however, that the TreeView will provide iterators to the sorted model. You must convert them to iterators to the underlying child model in order to perform actions on that model. For instance:NotebookNotice that the return value is of type <classname>sigc::signal&lt;void,int&gt;::iterator</classname>. This can be implicitly converted into a <classname>sigc::connection</classname> which in turn can be used to control the connection. By keeping a connection object you can disconnect its associated signal handler using the method <methodname>sigc::connection::disconnect()</methodname>.Notice that we provided <command>gmmproc</command> with the path to the .m4 convert files, the path to the .defs file, the name of a .hg file, the source directory, and the destination directory.Notice that we've used an initialiser statement to give the <literal>m_button</literal> object the label "Hello World".Notice, that after canceling an event, no other function will be called (even if it is from the same widget).Now let's look at our program's <function>main()</function> function. Here it is, without comments:Now let's look at the connection again:Now let's see what happens when an exception is thrown from a signal handler. Here's the source code. <placeholder-1/>Now let's take a look at the code that performs the actual drawing. The first section of <methodname>on_draw()</methodname> should be pretty familiar by now. This example again scales the coordinate system to be a unit square so that it's easier to draw the clock as a percentage of window size so that it will automatically scale when the window size is adjusted. Furthermore, the coordinate system is scaled over and down so that the (0, 0) coordinate is in the very center of the window.Now that there is a place to put your translations, you need to initialize <application>intltool</application> and <application>gettext</application>. Add the following code to your <literal>configure.ac</literal>, substituting 'programname' with the name of your program:Now that we understand the basics of the Cairo graphics library, we're almost ready to start drawing. We'll start with the simplest of drawing elements: the straight line. But first you need to know a little bit about Cairo's coordinate system. The origin of the Cairo coordinate system is located in the upper-left corner of the window with positive x values to the right and positive y values going down. <placeholder-1/>Now that we've covered the basics of drawing with Cairo, let's try to put it all together and create a simple application that actually does something. The following example uses Cairo to create a custom <classname>Clock</classname> widget. The clock has a second hand, a minute hand, and an hour hand, and updates itself every second.Now that you've seen signals and signal handlers in <application>gtkmm</application>, you might like to use the same technique to allow interaction between your own classes. That's actually very simple by using the <application>libsigc++</application> library directly.Now we edit the files to adapt them to our needs. You might prefer to use a multiple-file search-replace utility for this, such as <command>regexxer</command>. Note that nearly all of the files provided with the skeleton source tree contain placeholder text. Thus, the substitutions should be performed globally, and not be limited to the Automake and Autoconf files.OK, you say, that's nice, but what if I want to create my own handlers to respond when the user adjusts a <classname>Range</classname> widget or a <classname>SpinButton</classname>. To access the value of a <classname>Gtk::Adjustment</classname>, you can use the <methodname>get_value()</methodname> and <methodname>set_value()</methodname> methods:Objects and functions.Objects such as <classname>Gdk::Pixbuf</classname> can only be instantiated with a <methodname>create()</methodname> function. For instance, <placeholder-1/>Objects used via <classname>RefPtr</classname>: Pass the <classname>RefPtr</classname> as a const reference. For instance, <code>const Glib::RefPtr&lt;Gtk::FileFilter&gt;&amp; filter</code>.Occasionally you might want to make an <classname>Entry</classname> widget read-only. This can be done by passing <literal>false</literal> to the <methodname>set_editable()</methodname> method.Of course this means that you can store <classname>RefPtr</classname>s in standard containers, such as <classname>std::vector</classname> or <classname>std::list</classname>.Of course, a top-level container will not be added to another container. The programmer is responsible for destroying the top-level container using one of the traditional C++ techniques. For instance, your top-level Window might just be an instance in your <function>main()</function> function.Often when wrapping methods, it is desirable to store the return of the C function in what is called an output parameter. In this case, the C++ method returns <type>void</type> but an output parameter in which to store the value of the C function is included in the argument list of the C++ method. gmmproc allows such functionality, but appropriate initialization macros must be included to tell gmmproc how to initialize the C++ parameter from the return of the C function.OleOn Unix, the default preview handler uses an external viewer program. On Windows, the native preview dialog will be shown. If necessary you may override this behaviour and provide a custom preview dialog. See the example located in /examples/book/printing/advanced.Once you've built your software, you'll need to run your program within the jhbuild environment as well. To do this, you can again use the <command>jhbuild shell</command> command to start a new shell with the <application>jhbuild</application> environment set up. Alternatively, you can execute a one-off command in the <application>jhbuild</application> environment using the following command: <command>jhbuild run command-name</command>. In this case, the command will be run with the correct environment variables set, but will return to your previous environment after the program exits.Once you've configured <application>jhbuild</application> as described above, building <application>gtkmm</application> should be relatively straightforward. The first time you run <application>jhbuild</application>, you should run the following sequence of commands to ensure that <application>jhbuild</application> has the required tools and verify that it is set up correctly: <screen>$ jhbuild bootstrap
$ jhbuild sanitycheck</screen>One of the benefits of UTF-8 is that you don't need to use it unless you want to, so you don't need to retrofit all of your code at once. <classname>std::string</classname> will still work for 7-bit ASCII strings. But when you try to localize your application for languages like Chinese, for instance, you will start to see strange errors, and possible crashes. Then all you need to do is start using <classname>Glib::ustring</classname> instead.One of the major advantages of <application>gtkmm</application> is that it is crossplatform. <application>gtkmm</application> programs written on other platforms such as GNU/Linux can generally be transferred to Windows (and vice versa) with few modifications to the source.Openismus has more <ulink url="http://www.openismus.com/documents/linux/automake/automake.shtml">basic help with automake and autoconf</ulink>.Optional Parameter ProcessingOr you could specify the tag when first inserting the text: <placeholder-1/>Other macrosOther macros, such as <function>_WRAP_METHOD()</function> and <function>_WRAP_SIGNAL()</function> may only be used after a call to a <function>_CLASS_*</function> macro.Other than the signal's name (<literal>focus</literal>), two things are important to note here: the number following the word <classname>SignalProxy</classname> at the beginning (1, in this case), and the types in the list (<type>bool</type> and <type>Gtk::DirectionType</type>). The number indicates how many arguments the signal handler should have; the first type, <type>bool</type>, is the type that the signal handler should return; and the next type, <type>Gtk::DirectionType</type>, is the type of this signal's first, and only, argument. By looking at the reference documentation, you can see the names of the arguments too.Our examples all tend to have the same structure. They follow these steps for using a <classname>Widget</classname>:Output Parameter ProcessingOverriding default signal handlersOverviewPKG_CHECK_MODULES([MYAPP], [gtkmm-3.0 &gt;= 3.8.0])Pack the widget into a container using the appropriate call, e.g. <methodname>Gtk::Container::add()</methodname> or <methodname>pack_start()</methodname>.PackingPage setupPanedPanes divide a widget into two halves, separated by a moveable divider. The two halves (panes) can be oriented either horizontally (side by side) or vertically (one above the other).PangoParameter ReorderingParts of chapter on "Internationalization".Parts of the update from gtkmm 2 to gtkmm 3.PastePedroPer-child packing optionsPer-container packing optionsPermission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.2 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts. You may obtain a copy of the GNU Free Documentation License from the Free Software Foundation by visiting their Web site or by writing to: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.PitfallsPlease note that when reordering parameters for a <function>_WRAP_SIGNAL()</function> method signature, the C parameter names would always be <literal>p0</literal>, <literal>p1</literal>, etc. because the <filename>generate_extra_defs</filename> utility uses those parameter names no matter what the C API's parameter names may be. It's how the utility is written presently.Please see <ulink url="http://live.gnome.org/gtkmm/MSWindows/BuildingGtkmm">http://live.gnome.org/gtkmm/MSWindows/BuildingGtkmm</ulink> for instructions on how to build gtkmm on Windws.PlugsPlugs and SocketsPlugs and Sockets ExamplePopup Context MenuPopup MenuPopup Menu examplePopup MenusPrebuilt PackagesPreparing your projectPretty thrilling, eh? Let's examine the code. First, the <classname>HelloWorld</classname> class:Preventing row selectionPreviewPrintOperationPrintingPrinting - SimpleProbably the most common way of creating <classname>Gdk::Pixbuf</classname>s is to use <methodname>Gdk::Pixbuf::create_from_file()</methodname>, which can read an image file, such as a png file into a pixbuf ready for rendering.Problems in the C API.Programming with <application>gtkmm</application> 3Progress bars are used to show the status of an ongoing operation. For instance, a <classname>ProgressBar</classname> can show how much of a task has been completed.ProgressBarPush-ButtonsPuts the generated code in #ifdef blocks.Puts the generated code in #ifdef blocks. Text about the deprecation can be specified as an optional parameter.Radio buttonsRadioButtonRange WidgetsRe. Overriding signal handlers: You can do this in the straight-C world of GTK+ too; that's what GTK's object system is for. But in GTK+, you have to go through some complicated procedures to get object-oriented features like inheritance and overloading. In C++, it's simple, since those features are supported in the language itself; you can let the compiler do the dirty work.Recent versions of <application>gtkmm</application> are packaged by nearly every major Linux distribution these days. So, if you use Linux, you can probably get started with <application>gtkmm</application> by installing the package from the official repository for your distribution. Distributions that include <application>gtkmm</application> in their repositories include Debian, Ubuntu, Red Hat, Fedora, Mandriva, Suse, and many others.RecentChooserRecentManagerRecently Used DocumentsRecommended TechniquesReferenceRemember that on a Unix or Linux operating system, you will probably need to be <literal>root</literal> to install software. The <command>su</command> or <command>sudo</command> command will allow you to enter the <literal>root</literal> password and have <literal>root</literal> status temporarily.Remember that these names are just the identifiers that we used when creating the actions. They are not the text that the user will see in the menus and toolbars. We provided those human-readable names when we created the actions.Remember that you are not instantiating a widget with <methodname>get_widget()</methodname>, you are just obtaining a pointer to one that already exists. You will always receive a pointer to the same instance when you call <methodname>get_widget()</methodname> on the same <classname>Gtk::Builder</classname>, with the same widget name. The widgets are instantiated during <methodname>Gtk::Builder::create_from_file()</methodname>.Rendering textReorderable rowsResourcesResponding to changesReusing C documentationRiederRow childrenSame strings, different semanticsScale WidgetsScrollbar WidgetsScrolled windows have <emphasis>scrollbar policies</emphasis> which determine whether the <classname>Scrollbar</classname>s will be displayed. The policies can be set with the <methodname>set_policy()</methodname> method. The policy may be one of <literal>Gtk::POLICY_AUTOMATIC</literal> or <literal>Gtk::POLICY_ALWAYS</literal>. <literal>Gtk::POLICY_AUTOMATIC</literal> will cause the scrolled window to display the scrollbar only if the contained widget is larger than the visible area. <literal>Gtk::POLICY_ALWAYS</literal> will cause the scrollbar to be displayed always.ScrolledWindowScrollingSecond, check for an error and connect to the <literal>status_changed</literal> signal. For instance: <placeholder-1/>Section "Build Structure" of chapter on "Wrapping C Libraries with gmmproc".Section on Gtk::Grid.See <link linkend="sec-printing-example-simple">an example</link> of exactly how this can be done.See the <link linkend="chapter-draganddrop">Drag and Drop</link> chapter for general advice about Drag and Drop with gtkmm.See the <link linkend="chapter-internationalization">Internationalization</link> section for information about providing the UTF-8 string literals.See the <link linkend="chapter-refptr">appendix</link> for detailed information about RefPtr.See the <link linkend="sec-progressbar">ProgressBar</link> section for another example that uses an <classname>Alignment</classname>.Selecting which C++ types should be used is also important when wrapping C API. Though it's usually obvious what C++ types should be used in the C++ method, here are some hints: <placeholder-1/>Set the attributes of the widget. If the widget has no default constructor, then you will need to initialize the widget in the initalizer list of your container class's constructor.Set the title of the tab via <methodname>PrintOperation::set_custom_tab_label()</methodname>, create a new widget and return it from the <literal>create_custom_widget</literal> signal handler. You'll probably want this to be a container widget, packed with some others.Setting a prefixSetting up jhbuildSetting valuesShared resourcesShown below is a simple example of how to use the <classname>RecentChooserDialog</classname> and the <classname>RecentAction</classname> classes in a program. This simple program has a menubar with a <guimenuitem>Recent Files Dialog</guimenuitem> menu item. When you select this menu item, a dialog pops up showing the list of recently used files.Signal Handler sequenceSignalsSignals and properties.Signals usually have function pointers in the GTK struct, with a corresponding enum value and a <function>g_signal_new()</function> in the .c file.SimpleSimple Entry ExampleSimple ExampleSimple RecentChooserDialog exampleSimple Text ExampleSimple UseSimple text copy-paste functionality is provided for free by widgets such as <classname>Gtk::Entry</classname> and <classname>Gtk::TextView</classname>, but you might need special code to deal with your own data formats. For instance, a drawing program would need special code to allow copy and paste within a view, or between documents.Since a <classname>Plug</classname> is just a special type of <classname>Gtk::Window</classname> class, you can add containers or widgets to it like you would to any other window.Since the Cairo graphics library was written with support for multiple output targets (the X window system, PNG images, OpenGL, etc), there is a distinction between user-space and device-space coordinates. The mapping between these two coordinate systems defaults to one-to-one so that integer values map roughly to pixels on the screen, but this setting can be adjusted if desired. Sometimes it may be useful to scale the coordinates so that the full width and height of a window both range from 0 to 1 (the 'unit square') or some other mapping that works for your application. This can be done with the <methodname>Cairo::Context::scale()</methodname> function.Since this is very similar to the methods above this explanation should be sufficient to understand what's going on. However, here's a little example:Single or multiple selectionSingle-item ContainersSo far we've told you to perform actions in response to button-presses and the like by handling signals. That's certainly a good way to do things, but it's not the only way.So that a user can click on a <classname>TreeView</classname>'s column header to sort the <classname>TreeView</classname>'s contents, call <methodname>Gtk::TreeView::Column::set_sort_column()</methodname>, supplying the model column on which model should be sorted when the header is clicked. For instance:So that applications can react to changes, for instance when a user moves a scrollbar, <classname>Gtk::Adjustment</classname> has a <literal>value_changed</literal> signal. You can then use the <methodname>get_value()</methodname> method to discover the new value.So that the <classname>Entry</classname> can interact with the drop-down list of choices, you must specify which of your model columns is the text column, with <methodname>set_entry_text_column()</methodname>. For instance: <placeholder-1/>So you should either avoid this situation or use <ulink url="http://developer.gnome.org/glibmm/unstable/classGlib_1_1ustring.html"><function>Glib::ustring::compose()</function></ulink> which supports syntax such as: <placeholder-1/>So, for example, if you have a <classname>Scale</classname> widget, and you want to change the rotation of a picture whenever its value changes, you would create a signal handler like this:SocketsSome <application>gtkmm</application> widgets don't have associated X windows; they draw on their parents' windows. Because of this, they cannot receive events. Also, if they are incorrectly sized, they don't clip, so you can get messy overwriting etc. To receive events on one of these widgets, you can place it inside an <classname>EventBox</classname> widget and then call <methodname>Gtk::Widget::set_events()</methodname> on the EventBox before showing it.Some API related to gtkmm uses intermediate data containers, such as <classname>Glib::StringArrayHandle</classname>, instead of a specific Standard C++ container such as <classname>std::vector</classname> or <classname>std::list</classname>, though <application>gtkmm</application> itself now uses just <classname>std::vector</classname> since <application>gtkmm</application> 3.0.Some Widgets do not have an associated X-Window, so they therefore do not receive X events. This means that the signals described in the <link linkend="sec-xeventsignals">X event signals</link> section will not be emitted. If you want to capture events for these widgets you can use a special container called <classname>Gtk::EventBox</classname>, which is described in the <link linkend="sec-eventbox">EventBox</link> section.Some extra macros make this easier and consistent. Look in gtkmm's .m4 files for examples. For instance: <placeholder-1/>Some objects, such as <classname>Gdk::Pixbuf</classname>s and <classname>Pango::Font</classname>s, are obtained from a shared store. Therefore you cannot instantiate your own instances. These classes typically inherit from <classname>Glib::Object</classname>. Rather than requiring you to reference and unreference these objects, <application>gtkmm</application> uses the <classname>Glib::RefPtr&lt;&gt;</classname> smartpointer. Cairomm has its own smartpointer, <classname>Cairo::RefPtr&lt;&gt;</classname>.Some of the basic types that are used in C APIs have better alternatives in C++. For example, there's no need for a <type>gboolean</type> type since C++ has <type>bool</type>. The following list shows some commonly-used types in C APIs and what you might convert them to in a C++ wrapper library.Some thread safety rules on the use of <classname>Glib::Dispatcher</classname> still apply. As mentioned, a <classname>Glib::Dispatcher</classname> object must be constructed in the receiver thread (the thread in whose main loop it will execute its connected slots). By default this is the main program thread, although there is a <classname>Glib::Dispatcher</classname> constructor which can take the <classname>Glib::MainContext</classname> object of any thread which has a main loop. Only the receiver thread should call <methodname>connect()</methodname> on the <classname>Glib::Dispatcher</classname> object, or manipulate any related <classname>sigc::connection</classname> object, unless additional synchronization is employed. However, any worker thread can safely emit on the <classname>Glib::Dispatcher</classname> object without any locking once the receiver thread has connected the slots, provided that it is constructed before the worker thread is started (if it is constructed after the thread has started, additional synchronization will normally be required to ensure visibility).Sometimes two english strings are identical but have different meanings in different contexts, so they would probably not be identical when translated. Since the English strings are used as look-up keys, this causes problems.SortingSorting by clicking on columnsSource CodeSources and DestinationsSpecifies the destination directory for generated sources, and the name of the main .defs file that <command>gmmproc</command> should parse.Specifies the name of the slot parameter of the method, if it has one. This enables <command>gmmproc</command> to generate code to copy the slot and pass the copy on to the C function in its final <literal>gpointer user_data</literal> parameter. The <literal>slot_callback</literal> option must also be used to specify the name of the glue callback function to also pass on to the C function.Specifying CellRenderer detailsSpinButtonStart the <filename>plug</filename> program and send it to the background (or just use a different terminal).Stock items have been recommended for use in buttons. From <application>gtkmm</application>-3.10 they are deprecated. They should not be used in newly-written code. However, the documentation of <ulink url="http://developer.gnome.org/gtkmm/unstable/namespaceGtk_1_1Stock.html">namespace Gtk::Stock</ulink> shows recommended labels and named icons to show in buttons.String literals should be typed in the source code in English, but surrounded by a macro. The <application>gettext</application> (or intltool) utility can then extract the marked strings for translation, and substitute the translated text at runtime.String literals should be typed in the source code in English, but they should be surrounded by a call to the <function>gettext()</function> function. These strings will be extracted for translation and the translations may be used at runtime instead of the original English strings.Subclass Widgets to better organize your code. You should probably subclass your main <classname>Window</classname> at least. Then you can make your child Widgets and signal handlers members of that class.Subclassing isn't always the best way to accomplish things. It is only useful when you want the widget to handle its own signal by itself. If you want some other class to handle the signal then you'll need to connect a separate handler. This is even more true if you want several objects to handle the same signal, or if you want one signal handler to respond to the same signal from different objects.TableTagTableTagsTags and FormattingTargetsTells <command>gmmproc</command> not to pass a copy of the slot to the C function, if the method has one. Instead the slot itself is passed. The slot parameter name and the glue callback function must have been specified with the <literal>slot_name</literal> and <literal>slot_callbback</literal> options respectively.Tells <command>gmmproc</command> to add initialization code for the interface.Tells <command>gmmproc</command> to add some typedefs, constructors, and standard methods to this class, as appropriate when wrapping a widget.Tells <command>gmmproc</command> to include a header in the generated private/button_p.h file.Testing and adding translationsText is drawn via Pango Layouts. The easiest way to create a <classname>Pango::Layout</classname> is to use <methodname>Gtk::Widget::create_pango_layout()</methodname>. Once created, the layout can be manipulated in various ways, including changing the text, font, etc. Finally, the layout can be rendered using the <methodname>Pango::Layout::show_in_cairo_context()</methodname> method.Text rendering is done using Pango. The <classname>Pango::Layout</classname> object for printing should be created by calling the <methodname>PrintContext::create_pango_layout()</methodname> method. The <classname>PrintContext</classname> object also provides the page metrics, via <methodname>get_width()</methodname> and <methodname>get_height()</methodname>. The number of pages can be set with <methodname>PrintOperation::set_n_pages()</methodname>. To actually render the Pango text in <literal>on_draw_page</literal>, get a <classname>Cairo::Context</classname> with <methodname>PrintContext::get_cairo_context()</methodname> and show the <classname>Pango::LayoutLine</classname>s that appear within the requested page number.TextViewThat will create a file named <filename>programname.pot</filename>. Now copy that file to <filename>languagecode.po</filename>, such as <filename>de.po</filename> or <filename>hu.po</filename>. Also add that language code to <literal>LINGUAS</literal>. The <filename>.po</filename> file contains a header and a list of English strings, with space for the translated strings to be entered. Make sure you set the encoding of the <filename>.po</filename> file (specified in the header, but also as content) to <literal>UTF-8</literal>.The "changed" signalThe 'Print to file' option is available in the print dialog, without the need for extra implementation. However, it is sometimes useful to generate a pdf file directly from code. For instance, <placeholder-1/>The .h and .cc files will be generated from the .hg and .ccg files by processing them with <command>gmmproc</command> like so, though this happens automatically when using the above build structure: <placeholder-1/>The .hg and .ccg filesThe .hg and .ccg source files are very much like .h and .cc C++ source files, but they contain extra macros, such as <function>_CLASS_GOBJECT()</function> and <function>_WRAP_METHOD()</function>, from which <command>gmmproc</command> generates appropriate C++ source code, usually at the same position in the header. Any additional C++ source code will be copied verbatim into the corresponding .h or .cc file.The <application>GNU gettext</application> package allows you to mark strings in source code, extract those strings for translation, and use the translated strings in your application.The <application>gtkmm</application> module is defined in the <filename>gnome-suites-core-deps-3.x.modules</filename> moduleset, so edit your <filename>.jhbuildrc</filename> file and set your moduleset setting to the latest version e.g. like so: <placeholder-1/>The <classname>AboutDialog</classname> offers a simple way to display information about a program, like its logo, name, copyright, website and license.The <classname>Alignment</classname> widget allows you to place a widget at a position and size relative to the size of the <classname>Alignment</classname> widget itself. For instance, it might be used to center a widget.The <classname>AspectFrame</classname> widget looks like a <classname>Frame</classname> widget, but it also enforces the <emphasis>aspect ratio</emphasis> (the ratio of the width to the height) of the child widget, adding extra space if necessary. For instance, this would allow you to display a photograph without allowing the user to distort it horizontally or vertically while resizing.The <classname>ColorChooserDialog</classname> allows the user to choose a color. The <classname>ColorButton</classname> opens a color selection dialog when it is clicked.The <classname>ComboBox</classname> widget offers a list (or tree) of choices in a dropdown menu. If appropriate, it can show extra information about each item, such as text, a picture, a checkbox, or a progress bar. The <classname>ComboBox</classname> widget usually restricts the user to the available choices, but it can optionally have an <classname>Entry</classname>, allowing the user to enter arbitrary text if none of the available choices are suitable.The <classname>DrawingArea</classname> widget is a blank window that gives you the freedom to create any graphic you desire. Along with that freedom comes the responsibility to handle draw signals on the widget. When a widget is first shown, or when it is covered and then uncovered again it needs to redraw itself. Most widgets have code to do this, but the DrawingArea does not, allowing you to write your own draw signal handler to determine how the contents of the widget will be drawn. This is most often done by overriding the virtual <methodname>on_draw()</methodname> member function.The <classname>EntryCompletion</classname> may use a <classname>TreeModel</classname> containing possible entries, specified with <methodname>set_model()</methodname>. You should then call <methodname>set_text_column()</methodname> to specify which of your model columns should be used to match possible text entries.The <classname>FileChooserDialog</classname> is suitable for use with "Open" or "Save" menu items.The <classname>FontChooserDialog</classname> allows the user to choose a font. The <classname>FontButton</classname> opens a font chooser dialog when it is clicked.The <classname>Gdk::Pixbuf</classname> can be rendered by setting it as the source pattern of the Cairo context with <methodname>Gdk::Cairo::set_source_pixbuf()</methodname>. Then draw the image with either <methodname>Cairo::Context::paint()</methodname> (to draw the whole image), or <methodname>Cairo::Context::rectangle()</methodname> and <methodname>Cairo::Context::fill()</methodname> (to fill the specified rectangle). <methodname>set_source_pixbuf()</methodname> is not a member of <classname>Cairo::Context</classname>. It takes a <classname>Cairo::Context</classname> as its first parameter.The <classname>Gtk::Adjustment</classname> is created by its <methodname>create()</methodname> method which is as follows:The <classname>Gtk::Button</classname> widget has the following signals, but most of the time you will just handle the <literal>clicked</literal> signal:The <classname>Gtk::TreeView</classname> widget can contain lists or trees of data, in columns.The <classname>ListStore</classname> contains simple rows of data, and each row has no children.The <classname>PrintOperation</classname> class has a method called <methodname>set_default_page_setup()</methodname> which selects the default paper size, orientation and margins. To show a page setup dialog from your application, use the <methodname>Gtk::run_page_setup_dialog()</methodname> method, which returns a <classname>Gtk::PageSetup</classname> object with the chosen settings. Use this object to update a <classname>PrintOperation</classname> and to access the selected <classname>Gtk::PaperSize</classname>, <literal>Gtk::PageOrientation</literal> and printer-specific margins.The <classname>SpinButton</classname> can create a default <classname>Adjustment</classname>, which you can access via the <methodname>get_adjustment()</methodname> method, or you can specify an existing <classname>Adjustment</classname> in the constructor.The <classname>Tag</classname> class has many other properties.The <classname>TextView</classname> creates its own default <classname>TextBuffer</classname>, which you can access via the <methodname>get_buffer()</methodname> method.The <classname>TextView</classname> widget can be used to display and edit large amounts of formatted text. Like the <classname>TreeView</classname>, it has a model/view design. In this case the <classname>TextBuffer</classname> is the model.The <classname>ToolPalette</classname>'s items might be dragged or simply activated. For instance, the user might drag objects to a canvas to create new items there. Or the user might click an item to activate a certain brush size in a drawing application.The <classname>TreeModelColumnRecord</classname> class is used to keep track of the columns and their data types. You add <classname>TreeModelColumn</classname> instances to the <classname>ColumnRecord</classname> and then use those <classname>TreeModelColumns</classname> when getting and setting the data in model rows. You will probably find it convenient to derive a new <classname>TreeModelColumnRecord</classname> which has your <classname>TreeModelColumn</classname> instances as member data.The <classname>TreeStore</classname> contains rows of data, and each row may have child rows.The <classname>TreeView</classname> already allows you to show the same <classname>TreeModel</classname> in two <classname>TreeView</classname> widgets. If you need one of these TreeViews to sort the model differently than the other then you should use a <classname>TreeModelSort</classname> instead of just, for instance, <methodname>Gtk::TreeViewModel::set_sort_column()</methodname>. <classname>TreeModelSort</classname> is a model that contains another model, presenting a sorted version of that model. For instance, you might add a sorted version of a model to a <classname>TreeView</classname> like so:The <classname>Widget</classname> class has some special signals which correspond to the underlying X-Windows events. These are suffixed by <literal>_event</literal>; for instance, <methodname>Widget::signal_button_press_event()</methodname>.The <emphasis>update policy</emphasis> of a <classname>Range</classname> widget defines at what points during user interaction it will change the <literal>value</literal> field of its <classname>Gtk::Adjustment</classname> and emit the <literal>value_changed</literal> signal. The update policies, set with the <methodname>set_update_policy()</methodname> method, are: <placeholder-1/>The <filename>.defs</filename> files are text files, in a lisp format, that describe the API of a C library, including its <placeholder-1/>The <filename>configure</filename> script will check to make sure all of the required dependencies are already installed. If you are missing any dependencies, it will exit and display an error.The <filename>skeletonmm/codegen/generate_defs_and_docs.sh</filename> script generates all <filename>.defs</filename> files and the <filename>*_docs.xml</filename> file, described in the <link linkend="sec-wrapping-documentation">Documentation</link> section.The <function>AC_CONFIG_FILES()</function> block must mention the correct directory names, as described above.The <function>AC_CONFIG_HEADERS()</function> line is used to generate two or more configuration header files. The first header file in the list contains all configuration macros which are set during the configure run. The remaining headers in the list contain only a subset of configuration macros and their corresponding <filename>config.h.in</filename> file will not be autogenerated. The reason for this separation is that the namespaced configuration headers are installed with your library and define publically visible macros.The <function>AC_CONFIG_SRCDIR()</function> line must mention a file in our source tree. We can edit this later if we don't yet know the names of any of the files that we will create.The <function>AC_SUBST([SOMETHINGMM_MODULES], ['...'])</function> line may need to be modified to check for the correct dependencies.The <function>_CTOR_DEFAULT()</function> and <function>_WRAP_CTOR()</function> macros add constructors, wrapping the specified <function>*_new()</function> C functions. These macros assume that the C object has properties with the same names as the function parameters, as is usually the case, so that it can supply the parameters directly to a <function>g_object_new()</function> call. These constructors never actually call the <function>*_new()</function> C functions, because gtkmm must actually instantiate derived GTypes, and the <function>*_new()</function> C functions are meant only as convenience functions for C programmers.The <link linkend="chapter-draganddrop">Drag and Drop</link> API uses the same mechanism. You should probably use the same data targets and formats for both Clipboard and Drag and Drop operations.The <literal>const ... &amp;</literal> around both is just for efficiency, like using <classname>const std::string&amp;</classname> instead of <classname>std::string</classname> for a method parameter to avoid unnecessary copying.The <literal>ideal</literal> example below can supply more than one clipboard target.The <methodname>PrintOperation::run()</methodname> method starts the print loop, during which various signals are emitted: <placeholder-1/>The <methodname>get_request_mode_vfunc()</methodname>, <methodname>get_preferred_width_vfunc()</methodname>, <methodname>get_preferred_height_vfunc()</methodname>, <methodname>get_preferred_width_for_height_vfunc()</methodname>, <methodname>get_preferred_height_for_width_vfunc()</methodname>, and <methodname>on_size_allocate()</methodname> virtual methods control the layout of the child widgets. For instance, if your container has 2 child widgets, with one below the other, your <methodname>get_request_mode_vfunc()</methodname> might request height-for-width layout. Then your <methodname>get_preferred_width_vfunc()</methodname> might report the maximum of the widths of the child widgets, and <methodname>get_preferred_height_for_width_vfunc()</methodname> might report the sum of their heights. If you want padding between the child widgets then you would add that to the width and height too. Your widget's container will use this result to ensure that your widget gets enough space, and not less. By examining each widget's parent, and its parent, this logic will eventually decide the size of the top-level window.The <methodname>pack_start()</methodname> and <methodname>pack_end()</methodname> methods place widgets inside these containers. The <methodname>pack_start()</methodname> method will start at the top and work its way down in a <classname>Box</classname> with vertical orientation, or pack left to right in a <classname>Box</classname> with horizontal orientation. <methodname>pack_end()</methodname> will do the opposite, packing from bottom to top or from right to left. Using these methods allows us to right justify or left justify our widgets. We will use <methodname>pack_start()</methodname> in most of our examples.The <methodname>run()</methodname> method returns an <literal>int</literal>. This may be a value from the <literal>Gtk::ResponseType</literal> if the user closed the dialog by clicking a standard button, or it could be the custom response value that you specified when using <methodname>add_button()</methodname>.The <methodname>spin()</methodname> method 'spins' the <classname>SpinButton</classname>, as if its increment or decrement button had been clicked. You need to specify a <classname>Gtk::SpinType</classname> to specify the direction or new position.The <parameter>options</parameter> argument can take one of these three options: <placeholder-1/>The <parameter>padding</parameter> argument specifies the width of an extra border area to leave around the packed widget.The <parameter>value</parameter> argument is the initial value of the adjustment, usually corresponding to the topmost or leftmost position of an adjustable widget. The <parameter>lower</parameter> and <parameter>upper</parameter> arguments specify the possible range of values which the adjustment can hold. The <parameter>step_increment</parameter> argument specifies the smaller of the two increments by which the user can change the value, while the <parameter>page_increment</parameter> is the larger one. The <parameter>page_size</parameter> argument usually corresponds somehow to the visible area of a panning widget. The <parameter>upper</parameter> argument is used to represent the bottommost or rightmost coordinate in a panning widget's child.The BufferThe C function (e.g. <function>get_request_mode</function>) is described more fully in the <filename>*_vfuncs.defs</filename> file, and the <filename>convert*.m4</filename> files contain the necessary conversion from the C++ parameter type to the C parameter type.The C function (e.g. <function>gtk_entry_set_text</function>) is described more fully in the .defs file, and the <filename>convert*.m4</filename> files contain the necessary conversion from the C++ parameter type to the C parameter type. This macro also generates doxygen documentation comments based on the <filename>*_docs.xml</filename> and <filename>*_docs_override.xml</filename> files.The Cairo Drawing ModelThe Cairo coordinate system, in the <literal>draw_page</literal> handler, is automatically rotated to the current page orientation. It is normally within the printer margins, but you can change that via the <methodname>PrintOperation::set_use_full_page()</methodname> method. The default measurement unit is device pixels. To select other units, use the <methodname>PrintOperation::set_unit()</methodname> method.The ClipboardThe Drawing Area WidgetThe ModelThe RefPtr smartpointerThe SelectionThe TreeView widgetThe UI layout for a popup menu should use the <literal>popup</literal> node. For instance:The ViewThe View is the actual widget (<classname>Gtk::TreeView</classname>) that displays the model (<classname>Gtk::TreeModel</classname>) data and allows the user to interact with it. The View can show all of the model's columns, or just some, and it can show them in various ways.The adjustable widgets can be roughly divided into those which use and require specific units for these values, and those which treat them as arbitrary numbers.The arguments to <methodname>Action::create()</methodname> specify the action's name and how it will appear in menus and toolbars.The basic concept of drawing in Cairo involves defining 'invisible' paths and then stroking or filling them to make them visible.The build structureThe call to <methodname>Cairo::Context::curve_to()</methodname> should be fairly self-explanatory. The first pair of coordinates define the control point for the beginning of the curve. The second set of coordinates define the control point for the end of the curve, and the last set of coordinates define the destination point. To make the concept of control points a bit easier to visualize, a line has been drawn from each control point to the end-point on the curve that it is associated with. Note that these control point lines are both translucent. This is achieved with a variant of <methodname>set_source_rgb()</methodname> called <methodname>set_source_rgba()</methodname>. This function takes a fourth argument specifying the alpha value of the color (valid values are between 0 and 1).The chosen itemThe class macro declares the class itself and its relationship with the underlying C type. It generates some internal constructors, the member <varname>gobject_</varname>, typedefs, the <function>gobj()</function> accessors, type registration, and the <function>Glib::wrap()</function> method, among other things.The clear callback allows you to free the memory used by your stored data when the clipboard replaces its data with something else.The command line options passed to the C preprocessor.The command line options passed to the C++ compiler.The communication between a <classname>Socket</classname> and a <classname>Plug</classname> follows the XEmbed protocol. This protocol has also been implemented in other toolkits (e.g. Qt), which allows the same level of integration when embedding a Qt widget in GTK+ or vice versa.The compiler will complain if you use an inappropriate type. For instance, this would generate a compiler error:The connect*_once() variants, <methodname>Glib::SignalIdle::connect_once()</methodname>, <methodname>Glib::SignalTimeout::connect_once()</methodname>, <methodname>Glib::SignalTimeout::connect_seconds_once()</methodname>, are thread-safe for any case where the slot is not created by a call to <function>sigc::mem_fun()</function> which represents a method of a class deriving from <classname>sigc::trackable</classname>. This is similar to <methodname>Glib::Threads::Thread::create()</methodname> as mentioned in point 4.The constraintsThe constructor for <classname>ExampleWindow</classname> creates the menu using <classname>UIManager</classname> (see <xref linkend="chapter-menus-and-toolbars"/> for more information). It then adds the menu and the toolbar to the window.The constructor for <classname>Gtk::EventBox</classname> is:The current state of a <classname>Cairo::Context</classname> can be saved to an internal stack of saved states and later be restored to the state it was in when you saved it. To do this, use the <methodname>save()</methodname> method and the <methodname>restore()</methodname> method. This can be useful if you need to temporarily change the line width and color (or any other graphics setting) in order to draw something and then return to the previous settings. In this situation, you could call <methodname>Cairo::Context::save()</methodname>, change the graphics settings, draw the lines, and then call <methodname>Cairo::Context::restore()</methodname> to restore the original graphics state. Multiple calls to <methodname>save()</methodname> and <methodname>restore()</methodname> can be nested; each call to <methodname>restore()</methodname> restores the state from the matching paired <methodname>save()</methodname>. <placeholder-1/>The default <classname>CellRenderers</classname> and their default behaviour will normally suffice, but you might occasionally need finer control. For instance, this example code from <filename>gtkmm/demos/gtk-demo/example_treeview_treestore.cc</filename>, appends a <classname>Gtk::CellRenderer</classname> widget and instructs it to render the data from various model columns through various aspects of its appearance.The destination widget will emit these signals, in this order: <placeholder-1/>The drag and drop signals provide a DragContext, which contains some information about the drag and drop operation and can be used to influence the process. For instance, you can discover the source widget, or change the drag and drop icon, by using the <methodname>set_icon()</methodname> methods. More importantly, you should call the <methodname>drag_finish()</methodname> method from your <literal>drag_data_received</literal> signal handler to indicate whether the drop was successful.The easiest way to do this is using <ulink url="https://wiki.gnome.org/Jhbuild">jhbuild</ulink>. <application>jhbuild</application> is a program that makes building GNOME software much easier by calculating dependencies and building things in the correct order. This section will give a brief explanation of how to set up <application>jhbuild</application> to build and install <application>gtkmm</application> from the source repository (git). For up-to-date information on <application>jhbuild</application>, please refer to the <ulink url="http://developer.gnome.org/jhbuild/unstable/">jhbuild manual</ulink>. If you need assistance using <application>jhbuild</application>, you should ask for help on the <ulink url="http://mail.gnome.org/mailman/listinfo/gnome-love">gnome-love mailing list</ulink>.The entryThe event is delivered first to the widget the event occurred in. If all signal handlers in that widget return <literal>false</literal> (indicating that the event has not been handled), then the signal will be propagated to the parent widget and emitted there. This continues all the way up to the top-level widget if no one handles the event.The event will propagate until it reaches the top-level widget, or until you stop the propagation by returning <literal>true</literal> from an event handler.The example in examples/book/printing/advanced demonstrates this.The extra typedef allows the struct to be used in a header without including its full definition, simply by predeclaring it, by repeating that typedef. This means that you don't have to include the C library's header in your C++ header, thus keeping it out of your public API. <command>gmmproc</command> assumes that this technique was used, so you will see compiler errors if that is not the case.The first 6 methods in the previous table are also overridden in custom containers. They are briefly described in the <link linkend="sec-custom-containers">Custom Containers</link> section.The first argument is a <classname>slot</classname> you wish to have called when the timeout occurs. The second argument is the number of milliseconds between calls to that method. You receive a <classname>sigc::connection</classname> object that can be used to deactivate the connection using its <methodname>disconnect()</methodname> method:The first argument is a slot you wish to have called when the specified event (see argument 3) occurs on the file descriptor you specify using argument two. Argument three may be one or more (using <literal>|</literal>) of:The first argument is the widget you're packing. In our example these are all <classname>Button</classname>s.The first call to <methodname>connect()</methodname> is just like the one we saw last time; nothing new here.The first line of output is from <filename>plug</filename>, after it has been notified that it has been embedded inside of a <classname>Socket</classname>. The second line was emitted by <filename>socket</filename> in response to its <methodname>plug_added</methodname> signal. If everything was done as described above, the <filename>socket</filename> window should look roughly like the following:The following example demonstrates both uses of an <classname>EventBox</classname> - a label is created that is clipped to a small box, and set up so that a mouse-click on the label causes the program to exit. Resizing the window reveals varying amounts of the label.The following example demonstrates how to print some input from a user interface. It shows how to implement <literal>on_begin_print</literal> and <literal>on_draw_page</literal>, as well as how to track print status and update the print settings.The following example demonstrates the use of <classname>RadioButton</classname>s:The following example program requires a command-line option. The source code shows two ways of handling command-line options in combination with <classname>Gtk::Application</classname>.The following example shows how to set up a Cairo context with a foreground color of red and a width of 2. Any drawing functions that use this context will use these settings.The following is a simple example of using sockets and plugs. The method of communication between processes is deliberately kept very simple: The <classname>Plug</classname> writes its ID out to a text file named <filename>plug.id</filename> and the process with the socket reads the ID from this file. In a real program, you may want to use a more sophisticated method of inter-process communication.The following program uses a <classname>Gtk::AspectFrame</classname> to present a drawing area whose aspect ratio will always be 2:1, no matter how the user resizes the top-level window.The function <methodname>Cairo::Context::arc_negative()</methodname> is exactly the same as <methodname>Cairo::Context::arc()</methodname> but the angles go the opposite direction.The function <methodname>Cairo::Context::paint()</methodname> is used here to set the background color of the window. This function takes no arguments and fills the current surface (or the clipped portion of the surface) with the source color currently active. After setting the background color of the window, we draw a circle for the clock outline, fill it with white, and then stroke the outline in black. Notice that both of these actions use the <methodname>_preserve</methodname> variant to preserve the current path, and then this same path is clipped to make sure that our next lines don't go outside the outline of the clock.The functions <methodname>move_item()</methodname>, <methodname>remove_item()</methodname> and <methodname>purge_items()</methodname> have no effect on the actual files that are referred to by the URIs, they only modify the list of recent files.The group which treats the values as arbitrary numbers includes the <classname>Range</classname> widgets (<classname>Scrollbar</classname> and <classname>Scale</classname>), the <classname>ScaleButton</classname> widget, and the <classname>SpinButton</classname> widget. These widgets are typically "adjusted" directly by the user with the mouse or keyboard. They will treat the <parameter>lower</parameter> and <parameter>upper</parameter> values of an adjustment as a range within which the user can manipulate the adjustment's <parameter>value</parameter>. By default, they will only modify the <parameter>value</parameter> of an adjustment.The implementation of the <function>wrap_init()</function> method in <filename>wrap_init.cc</filename> is generated by <filename>generate_wrap_init.pl</filename>, but the declaration in <filename>wrap_init.h</filename> is hand-coded, so you will need to adjust <filename>wrap_init.h</filename> so that the <function>wrap_init()</function> function appears in the correct C++ namespace.The label text can be justified using the <methodname>set_justify()</methodname> method. The widget is also capable of word-wrapping, which can be activated with <methodname>set_line_wrap()</methodname>.The last line shows the window and enters the <application>gtkmm</application> main processing loop, which will finish when the window is closed. Your <function>main()</function> function will then return with an appropriate success or error code.The line join style is set using the function <methodname>Cairo::Context::set_line_join()</methodname>.The list is provided via a <classname>TreeModel</classname>, and columns from this model are added to the ComboBox's view with the <methodname>ComboBox::pack_start()</methodname> method. This provides flexibility and compile-time type-safety, but the <classname>ComboBoxText</classname> class provides a simpler text-based specialization in case that flexibility is not required.The macros are explained in more detail in the following sections.The macros in this example do the following: <placeholder-1/>The macros that you use in the .hg and .ccg files often need to know how to convert a C++ type to a C type, or vice-versa. gmmproc takes this information from an .m4 file in your <literal>tools/m4/</literal> directory. This allows it to call a C function in the implementation of your C++ method, passing the appropriate parameters to that C functon. For instance, this tells gmmproc how to convert a GtkTreeView pointer to a Gtk::TreeView pointer: <placeholder-1/>The main activity in the internationalization process is finding strings seen by users and marking them for translation. You do not need to do it all at once - if you set up the necessary project infrastructure correctly then your application will work normally regardless of how many strings you've covered.The maximum age of items in the recently used files list can be set with <methodname>Gtk::Settings::property_gtk_recent_files_max_age()</methodname>. Default value: 30 days.The modelThe model for a ComboBox can be defined and filled exactly as for a <classname>TreeView</classname>. For instance, you might derive a ComboBox class with one integer and one text column, like so:The name of the library, such as libsomethingmm.The names of the <application>gtkmm</application> packages vary from distribution to distribution (e.g. <application>libgtkmm-3.0-dev</application> on Debian and Ubuntu or <application>gtkmm30-devel</application> on Red Hat Fedora), so check with your distribution's package management program for the correct package name and install it like you would any other package.The native GTK+ print dialog has a preview button, but you may also start a preview directly from an application: <placeholder-1/>The next is more interesting. <function>sigc::mem_fun()</function> is called with two arguments. The first argument is <parameter>some_object</parameter>, which is the object that our new slot will be pointing at. The second argument is a pointer to one of its methods. This particular version of <function>sigc::mem_fun()</function> creates a slot which will, when "called", call the pointed-to method of the specified object, in this case <methodname>some_object.on_button_clicked()</methodname>.The next statement: <placeholder-1/> creates a <classname>Gtk::Application</classname> object, stored in a <classname>RefPtr</classname> smartpointer. This is needed in all <application>gtkmm</application> applications. The <methodname>create()</methodname> method for this object initializes <application>gtkmm</application>, and checks the arguments passed to your application on the command line, looking for standard options such as <literal>--display</literal>. It takes these from the argument list, leaving anything it does not recognize for your application to parse or ignore. This ensures that all <application>gtkmm</application> applications accept the same set of standard arguments.The next two lines of code create a window and set its default (initial) size:The number of decimal places can be altered using the <methodname>set_digits()</methodname> method.The only difference between this example and the straight line example is in the <methodname>on_draw()</methodname> function, but there are a few new concepts and functions introduced here, so let's examine them briefly.The orientation of a <classname>Gtk::Scrollbar</classname> can be either horizontal or vertical.The other group includes the <classname>Viewport</classname> widget and the <classname>ScrolledWindow</classname> widget. All of these widgets use pixel values for their adjustments. These are also typically adjusted indirectly using scrollbars. While all widgets which use adjustments can either create their own adjustments or use ones you supply, you'll generally want to let this particular category of widgets create its own adjustments.The package names will not change when new API/ABI-compatible versions of <application>gtkmm</application> are released. Otherwise they would not be API/ABI-compatible. So don't be surprised, for instance, to find <application>gtkmm</application> 3.8 supplied by Debian's <application>libgtkmm-3.0-dev</application> package.The primary disadvantage of using class scope widgets is revealing the class implementation rather than the class interface in the class header.The primary object is <classname>Gtk::PrintOperation</classname>, allocated for each print operation. To handle page drawing connect to its signals, or inherit from it and override the default virtual signal handlers. <classname>PrintOperation</classname> automatically handles all the settings affecting the print loop.The process of writing source code that allows for translation is called <literal>internationalization</literal>, often abbreviated to <literal>i18n</literal>. The <literal>Localization</literal> process, sometimes abbreviated as <literal>l10n</literal>, provides translated text for other languages, based on that source code.The progress bar can also display a configurable text string within its trough, using the <methodname>set_text()</methodname> method.The purpose of this example is to show the steps the event takes when it is emitted.The return value is a <classname>sigc::connection</classname> that may be used to stop monitoring this file descriptor using its <methodname>disconnect()</methodname> method. The <parameter>slot</parameter> signal handler should be declared as follows:The rulesThe same principles apply for signals which have more arguments. Here's one with three (taken from <filename>&lt;gtkmm/textbuffer.h&gt;</filename>):The second way to set up radio buttons is to make a group first, and then add radio buttons to it. Here's an example:The section for drawing an arc introduces one new function, <methodname>close_path()</methodname>. This function will in effect draw a straight line from the current point back to the first point in the path. There is a significant difference between calling <methodname>close_path()</methodname> and manually drawing a line back to the starting point, however. If you use <methodname>close_path()</methodname>, the lines will be nicely joined together. If you use <methodname>line_to()</methodname> instead, the lines will end at the same point, but Cairo won't do any special joining.The selected rowsThe signal handler is <methodname>on_button_clicked()</methodname>.The single-item container widgets derive from <classname>Gtk::Bin</classname>, which provides the <methodname>add()</methodname> and <methodname>remove()</methodname> methods for the child widget. Note that <classname>Gtk::Button</classname> and <classname>Gtk::Window</classname> are technically single-item containers, but we have discussed them already elsewhere.The slots connected to <classname>sigc::signal</classname> objects execute in the thread which calls <methodname>emit()</methodname> or <methodname>operator()()</methodname> on the signal. <classname>Glib::Dispatcher</classname> does not behave this way: instead its connected slots execute in the thread in which the <classname>Glib::Dispatcher</classname> object was constructed (which must have a glib main loop). If a <classname>Glib::Dispatcher</classname> object is constructed in the main GUI thread (which will therefore be the receiver thread), any worker thread can emit on it and have the connected slots safely execute <application>gtkmm</application> functions.The source widget will emit these signals, in this order: <placeholder-1/>The standard tree models (<classname>TreeStore</classname> and <classname>ListStore</classname>) derive from <classname>TreeSortable</classname>, so they offer sorting functionality. For instance, call <methodname>set_sort_column()</methodname>, to sort the model by the specified column. Or supply a callback function to <methodname>set_sort_func()</methodname> to implement a more complicated sorting algorithm.The text columnThe trick is to position in the middle of the pixel where you want the line to be drawn, and thus guaranteeing you get the desired results. See <ulink url="http://cairographics.org/FAQ/#sharp_lines">Cairo FAQ</ulink>.The use of the <literal>const</literal> keyword in C++ is not always clear. You might not realise that <type>const Something*</type> declares a pointer to a <type>const Something</type>. The pointer can be changed, but not the <type>Something</type> that it points to.The value can have an adjustable number of decimal places, and the step size is configurable. <classname>SpinButton</classname>s have an 'auto-repeat' feature as well: holding down the increment or decrement button can optionally cause the value to change more quickly the longer the button is held down.The value displayed by a scale widget is rounded to one decimal point by default, as is the <literal>value</literal> field in its <classname>Gtk::Adjustment</classname>. You can change this with the <methodname>set_digits()</methodname> method.The virtual <methodname>on_draw()</methodname> method provides a Cairo context that you shall use for drawing in the <classname>Gtk::DrawingArea</classname> widget. It is not necessary to save and restore this Cairo context in <methodname>on_draw()</methodname>.The way it works is that you upload your source code to a git repository where translators can access it, then contact the gnome-i18n mailing list and ask to have your program added to the <ulink url="http://l10n.gnome.org/module/">list of modules to translate</ulink>.The way that <classname>Sockets</classname> and <classname>Plugs</classname> work together is through their window ids. Both a <classname>Socket</classname> and a <classname>Plug</classname> have IDs that can be retrieved with their <methodname>get_id()</methodname> member functions. The use of these IDs will be explained below in <xref linkend="sec-connecting-plugs-sockets"/>.The widgets don't rearrange themselves when the window is resized. Some widgets are hidden when the window is made smaller, and lots of useless space appears when the window is made larger.The width of the label will be adjusted automatically. You can produce multi-line labels by putting line breaks ("\n") in the label string.The window ID is: 69206019Then edit the <filename>.cc</filename> file to specify the correct types. For instance, your <function>main()</function> function might look like this: <placeholder-1/>Then start the <filename>socket</filename> program:Then use <methodname>append_column()</methodname> to add the view Column to the View. Notice that <methodname>Gtk::TreeView::append_column()</methodname> is overridden to accept either a prebuilt <classname>Gtk::TreeView::Column</classname> widget, or just the <classname>TreeModelColumn</classname> from which it generates an appropriate <classname>Gtk::TreeView::Column</classname> widget.Then you make sure you update the file <filename>POTFILES.in</filename> in the <filename>po/</filename> subdirectory (<command>intltool-update -M</command> can help with this) so that the translators always access updated <filename>myprogram.pot</filename> files, and simply freeze the strings at least a couple of days before you make a new release, announcing it on gnome-i18n. Depending on the number of strings your program contains and how popular it is, the translations will then start to tick in as <filename>languagename.po</filename> files.Then, to add a widget at that position, use <methodname>Gtk::TextView::add_child_at_anchor()</methodname>:Then, you can define the actual visible layout of the menus and toolbars, and add the UI layout to the <classname>UIManager</classname>. This "ui string" uses an XML format, in which you should mention the names of the actions that you have already created. For instance:There are a couple of things to note about this example code. Again, the only real difference between this example and the previous ones is the <methodname>on_draw()</methodname> function, so we'll limit our focus to that function. In addition, the first part of the function is nearly identical to the previous examples, so we'll skip that portion.There are a few common mistakes that you would discover eventually yourself. But this section might help you to avoid them.There are a number of graphics state variables that can be set for a Cairo context. The most common context attributes are color (using <methodname>set_source_rgb()</methodname> or <methodname>set_source_rgba()</methodname> for translucent colors), line width (using <methodname>set_line_width()</methodname>), line dash pattern (using <methodname>set_dash()</methodname>), line cap style (using <methodname>set_line_cap()</methodname>), and line join style (using <methodname>set_line_join()</methodname>), and font styles (using <methodname>set_font_size()</methodname>, <methodname>set_font_face()</methodname> and others). There are many other settings as well, such as transformation matrices, fill rules, whether to perform antialiasing, and others. For further information, see the <ulink url="http://www.cairographics.org/cairomm/">cairomm</ulink> API documentation.There are basically five different styles, as shown in this picture:There are other things you can customize as well, including creating dashed lines and other things. For more information, see the Cairo API documentation.There are several derived <classname>Dialog</classname> classes which you might find useful. <classname>Gtk::MessageDialog</classname> is used for most simple notifications. But at other times you might need to derive your own dialog class to provide more complex functionality.There are several options governing how widgets are to be packed, and this can be confusing at first. If you have difficulties then it is sometimes a good idea to play with the <application>glade</application> GUI designer to see what is possible. You might even decide to use the <application>Gtk::Builder</application> API to load your GUI at runtime.There are several other containers, which we will also discuss.There are some optional extra arguments: <placeholder-1/>There are specific APIs for Menus and toolbars, but you should usually deal with them together, using the <classname>UIManager</classname> to define <classname>Action</classname>s which you can then arrange in menus and toolbars. In this way you can handle activation of the action instead of responding to the menu and toolbar items separately. And you can enable or disable both the menu and toolbar item via the action.There are two basic strategies that can be used: <placeholder-1/>There are two built-in <classname>Mark</classname>s - <literal>insert</literal> and <literal>selection_bound</literal>, which you can access with <classname>TextBuffer</classname>'s <methodname>get_insert()</methodname> and <methodname>get_selection_bound()</methodname> methods.There are two ways to create a Button. You can specify a label string in the <classname>Gtk::Button</classname> constructor, or set it later with <methodname>set_label()</methodname>.There are two ways to set up a group of radio buttons. The first way is to create the buttons, and set up their groups afterwards. Only the first two constructors are used. In the following example, we make a new window class called <classname>RadioButtons</classname>, and then put three radio buttons in it:There is a method for drawing from a <classname>Gdk::Pixbuf</classname> to a <classname>Cairo::Context</classname>. A <classname>Gdk::Pixbuf</classname> buffer is a useful wrapper around a collection of pixels, which can be read from files, and manipulated in various ways.There is a more complex example in examples/others/dnd.There is one optional extra argument: <placeholder-1/>There may be times when you need to modify the list of recent files. For instance, if a file is moved or renamed, you may need to update the file's location in the recent files list so that it doesn't point to an incorrect location. You can update an item's location by using <methodname>move_item()</methodname>.There's rather a lot to think about in this (non-functional) code. First let's identify the parties involved:Therefore, the <classname>RefPtr</classname> equivalent of <type>Something*</type> for a method parameter is <type>const Glib::RefPtr&lt;Something&gt;&amp;</type>, and the equivalent of <type>const Something*</type> is <type>const Glib::RefPtr&lt;const Something&gt;&amp;</type>.These are standard scrollbars. They should be used only to scroll another widget, such as, a <classname>Gtk::Entry</classname>, or a <classname>Gtk::Viewport</classname>, though it's usually easier to use the <classname>Gtk::ScrolledWindow</classname> widget in most cases.These dependencies have their own dependencies, including the following applications and libraries:These interactions arise from the fact that, amongst other things, a class inheriting from <classname>sigc::trackable</classname> will, via that inheritance, have a <classname>std::list</classname> object keeping track of slots created by calls to <function>sigc::mem_fun()</function> representing any of its non-static methods (more particularly it keeps a list of callbacks which will null the connected slots on its destruction). Each <classname>sigc::slot</classname> object also keeps, via <classname>sigc::slot_rep</classname>, its own <classname>sigc::trackable</classname> object to track any <classname>sigc::connection</classname> objects which it needs to inform about its demise, and also has a function to deregister itself from any <classname>sigc::trackable</classname> on disconnection or destruction. <classname>sigc::signal</classname> objects also keep lists of slots, which will be updated by a call to their <methodname>connect()</methodname> method or calls to any <classname>sigc::connection</classname> object relating to such a connection.These signals behave slightly differently. The value returned from the signal handler indicates whether it has fully "handled" the event. If the value is <literal>false</literal> then <application>gtkmm</application> will pass the event on to the next signal handler. If the value is <literal>true</literal> then no other signal handlers will need to be called.These widgets are mainly used for decoration or layout, so you won't often need to capture events on them. They are intended to have no X-Window in order to improve performance.Things are dragged from <literal>sources</literal> to be dropped on <literal>destinations</literal>. Each source and destination has infomation about the data formats that it can send or receive, provided by <classname>Gtk::TargetEntry</classname> items. A drop destination will only accept a dragged item if they both share a compatible <classname>Gtk::TargetEntry</classname> item. Appropriate signals will then be emitted, telling the signal handlers which <classname>Gtk::TargetEntry</classname> was used.This <filename>.defs</filename> file describes enum types and their possible values. It is generated by the <filename>enum.pl</filename> script which you can find in glibmm's <filename>tools</filename> directory. For instance, <placeholder-1/>This <filename>.defs</filename> file describes objects and their functions. It is generated by the <command>h2def.py</command> script which you can find in glibmm's <filename>tools/defs_gen</filename> directory. For instance, <placeholder-1/>This <filename>.defs</filename> file describes signals and properties. It is generated by the special <filename>generate_extra_defs</filename> utility that is in every wrapping project, such as <filename>gtkmm/tools/extra_defs_gen/</filename>. For instance <placeholder-1/>This <filename>.defs</filename> file describes virtual functions (vfuncs). It must be written by hand. There is the skeleton file <filename>skeleton/src/skeleton_vfunc.defs</filename> to start from. You can also look at <application>gtkmm</application>'s <filename>gtk/src/gtk_vfuncs.defs</filename> file.This <varname>PROGRAMNAME_LOCALEDIR</varname> variable will be used later in the <literal>Makefile.am</literal> file, to define a macro that will be used when you initialize <application>gettext</application> in your source code.This allows language bindings to implement their own equivalents (such as C++ constructors), without using the <function>*_new()</function> function. This is often necessary so that they can actually instantiate a derived GType, to add their own hooks for signal handlers and vfuncs.This bookThis book assumes a good understanding of C++, and how to create C++ programs.This book explains key concepts of the <application>gtkmm</application> C++ API for creating user interfaces. It also introduces the main user interface elements ("widgets").This book explains key concepts of the <application>gtkmm</application> C++ API for creating user interfaces. It also introduces the main user interface elements ("widgets"). Although it mentions classes, constructors, and methods, it does not go into great detail. Therefore, for full API information you should follow the links into the reference documentation.This causes <application>gtkmm</application> to call the specified method whenever nothing else is happening. You can add a priority (lower numbers are higher priorities). There are two ways to remove the signal handler: calling <methodname>disconnect()</methodname> on the <classname>sigc::connection</classname> object, or returning <literal>false</literal> in the signal handler, which should be declared as follows:This chapter will introduce some of the most important aspects of <application>gtkmm</application> coding. These will be demonstrated with simple working example code. However, this is just a taster, so you need to look at the other chapters for more substantial information.This class implements the "Hello World" window. It's derived from <classname>Gtk::Window</classname>, and has a single <classname>Gtk::Button</classname> as a member. We've chosen to use the constructor to do all of the initialisation work for the window, including setting up the signals. Here it is, with the comments omitted:This command will build and install a series of modules and will probably take quite a long time the first time through. After the first time, however, it should go quite a bit faster since it only needs to rebuild files that changed since the last build. Alternatively, after you've built and installed <application>gtkmm</application> the first time, you can rebuild <application>gtkmm</application> by itself (without rebuilding all of its dependencies) with the command <command>jhbuild buildone gtkmm</command>.This compiler error might look like this: <placeholder-1/> or this: <placeholder-2/>This document, like so much other great software out there, was created for free by volunteers. If you are at all knowledgeable about any aspect of <application>gtkmm</application> that does not already have documentation, please consider contributing to this document.This example adds a <classname>ToolPalette</classname> and a <classname>DrawingArea</classname> to a window and allows the user to drag icons from the tool palette to the drawing area. The tool palette contains several groups of items. The combo boxes allow the user to change the style and orientation of the tool palette.This example allows copy and pasting of application-specific data, using the standard text target. Although this is simple, it's not ideal because it does not identify the <classname>Clipboard</classname> data as being of a particular type.This example creates a <classname>Gtk::EntryCompletion</classname> and associates it with a <classname>Gtk::Entry</classname> widget. The completion uses a <classname>Gtk::TreeModel</classname> of possible entries, and some additional actions.This example creates a button with a picture and a label.This example creates a window with three buttons in a grid. The first two buttons are in the upper row, from left to right. A third button is attached underneath the first button, in a new lower row, spanning two columns.This example creates two executable programs: <filename>socket</filename> and <filename>plug</filename>. The idea is that <filename>socket</filename> has an application window that will embed a widget from the <filename>plug</filename> program. The way this example is designed, <filename>plug</filename> must be running first before starting <filename>socket</filename>. To see the example in action, execute the following commands in order from within the example directory:This example displays a window with three range widgets all connected to the same adjustment, along with a couple of controls for adjusting some of the parameters mentioned above and in the section on adjustments, so you can see how they affect the way these widgets work for the user.This example has a <classname>Gtk::TreeView</classname> widget, with a <classname>Gtk::ListStore</classname> model.This example implements a container with two child widgets, one above the other. Of course, in this case it would be far simpler just to use a vertical <classname>Gtk::Box</classname>.This example implements a widget which draws a Penrose triangle.This example is identical to the <classname>ListStore</classname> example, but it uses <methodname>TreeView::append_column_editable()</methodname> instead of <methodname>TreeView::append_column()</methodname>.This example is much like the <classname>ListStore</classname> example, but derives a custom <classname>TreeView</classname> in order to override the <literal>button_press_event</literal>, and also to encapsulate the tree model code in our derived class. See the <link linkend="sec-treeview-contextmenu">TreeView Popup Context Menu</link> section.This example is much like the <classname>TreeStore</classname> example, but has 2 extra columns to indicate whether the row can be dragged, and whether it can receive drag-and-dropped rows. It uses a derived <classname>Gtk::TreeStore</classname> which overrides the virtual functions as described in the <link linkend="sec-treeview-draganddrop">TreeView Drag and Drop</link> section.This example is very similar to the <classname>ListStore</classname> example, but uses a <classname>Gtk::TreeStore</classname> model instead, and adds children to the rows.This example points out the difference of idle and timeout methods a little. If you need methods that are called periodically, and speed is not very important, then you want timeout methods. If you want methods that are called as often as possible (like calculating a fractal in background), then use idle methods.This example right-aligns a button in a window by using an <classname>Alignment</classname> widget.This example shows a <classname>Gtk::Entry</classname> widget with a named search icon, and prints text to the terminal when the icon is pressed.This example shows a <classname>Gtk::Entry</classname> widget with a progress bar.This example shows how to load a <application>Glade</application> file at runtime and access the widgets via a derived class.This example uses <classname>Gtk::Entry</classname>. It also has two <classname>CheckButton</classname>s, with which you can toggle the editable and visible flags.This exception can then be thrown by methods which are generated from _WRAP_METHOD() with the errthrow option.This has the following advantages: <placeholder-1/>This involves a variety of tools, some of them crufty, but at least they work, and has been used successfully by several projects.This involves the use of the <classname>Gtk::ActionGroup</classname>, <classname>Gtk::Action</classname>, and <classname>UIManager</classname> classes, all of which should be instantiated via their <methodname>create()</methodname> methods, which return <classname>RefPtr</classname>s.This is a full working example that defines and uses custom signals.This is an example program with two threads, one GUI thread, like in all <application>gtkmm</application> programs, and one worker thread. The worker thread is created when you press the <literal>Start work</literal> button. It is deleted when the work is finished, when you press the <literal>Stop work</literal> button, or when you press the <literal>Quit</literal> button.This is demonstrated in the Popup Context Menu example.This is demonstrated in the drag_and_drop example.This is easy to correct in the C library, so do send a patch to the relevant maintainer.This is like the simple example, but it <placeholder-1/>This is one of the places where the beauty of C++ really comes out. One wouldn't think of subclassing a GTK+ widget simply to override its action method; it's just too much trouble. In GTK+, you almost always use signals to get things done, unless you're writing a new widget. But because overriding methods is so easy in C++, it's entirely practical - and sensible - to subclass a button for that purpose.This is the declaration of the <methodname>pack_start()</methodname> method:This isn't purely a <application>gtkmm</application> or GUI issue. <application>gtkmm</application> uses <application>libsigc++</application> to implement its proxy wrappers for the <application>GTK+</application> signal system, but for new, non-GTK+ signals, you can create pure C++ signals, using the <classname>sigc::signal&lt;&gt;</classname> template.This macro can be used to wrap structs which don't fit into any specialized category.This macro creates a constructor with arguments, equivalent to a <function>*_new()</function> C function. It won't actually call the <function>*_new()</function> function, but will simply create an equivalent constructor with the same argument types. It takes a C++ constructor signature, and a C function name.This macro creates a default constructor with no arguments.This macro declares a wrapper for a non-<classname>GObject</classname> struct, registered with <function>g_boxed_type_register_static()</function>.This macro declares a wrapper for a reference-counted opaque struct. The C++ wrapper cannot be directly instantiated and can only be used with <classname>Glib::RefPtr</classname>.This macro declares a wrapper for a simple assignable struct such as <classname>GdkRectangle</classname>. It is similar to <function>_CLASS_BOXEDTYPE</function>, but the C struct is not allocated dynamically.This macro declares a wrapper for a type that is derived from <classname>GObject</classname>, but whose wrapper is not derived from <classname>Gtk::Object</classname>.This macro declares a wrapper for a type that is derived from <classname>GTypeInterface</classname>.This macro declares a wrapper for a type whose wrapper is derived from <classname>Gtk::Object</classname>, such as a widget or dialog.This macro declares a wrapper for an opaque struct that has copy and free functions. The new, copy and free functions will be used to instantiate the default constructor, copy constructor and destructor.This macro generates a C++ enum to wrap a C enum. You must specify the desired C++ name and the name of the underlying C enum.This macro generates a C++ exception class, derived from Glib::Error, with a Code enum and a code() method. You must specify the desired C++ name, the name of the corresponding C enum, and the prefix for the C enum values.This macro generates initialization code for the interface.This macro generates the C++ libsigc++-style signal to wrap a C GObject signal. It actually generates a public accessor method, such as <function>signal_clicked()</function>, which returns a proxy object. <command>gmmproc</command> uses the .defs file to discover the C parameter types and the .m4 convert files to discover appropriate type conversions.This macro generates the C++ method to wrap a C GObject property. You must specify the property name and the wanted C++ type for the property. <command>gmmproc</command> uses the .defs file to discover the C type and the .m4 convert files to discover appropriate type conversions.This macro generates the C++ method to wrap a C function.This macro generates the C++ method to wrap a virtual C function.This macro is like <function>_WRAP_METHOD()</function>, but it generates only the documentation for a C++ method that wraps a C function. Use this when you must hand-code the method, but you want to use the documentation that would be generated if the method was generated.This macro just generates a Doxygen documentationn block for the enum. This is useful for enums that can't be wrapped with <function>_WRAP_ENUM()</function> because they are complexly defined (maybe using C macros) but including the generated enum documentation is still desired. It is used with the same syntax as <function>_WRAP_ENUM()</function> and also process the same options (though NO_GTYPE is just ignored because it makes no difference when just generating the enum's documentation).This macro will be used when you initialize <literal>gettext</literal> in your source code.This means that any method which takes a <type>const Glib::RefPtr&lt;BaseType&gt;</type> argument can also take a <type>const Glib::RefPtr&lt;DerivedType&gt;</type>. The cast is implicit, just as it would be for a normal pointer.This program contains a single class, <classname>MyArea</classname>, which is a subclass of <classname>Gtk::DrawingArea</classname> and contains an <methodname>on_draw()</methodname> member function. This function is called whenever the image in the drawing area needs to be redrawn. It is passed a <classname>Cairo::RefPtr</classname> pointer to a <classname>Cairo::Context</classname> that we use for the drawing. The actual drawing code sets the color we want to use for drawing by using <methodname>set_source_rgb()</methodname> which takes arguments defining the Red, Green, and Blue components of the desired color (valid values are between 0 and 1). After setting the color, we created a new path using the functions <methodname>move_to()</methodname> and <methodname>line_to()</methodname>, and then stroked this path with <methodname>stroke()</methodname>.This provides a directory structure for the source .hg and .ccg files and the generated .h and .cc files, with <filename>filelist.am</filename> Automake include files that can specify the various files in use, in terms of generic Automake variables. The directory structure usually looks like this, after we have renamed the directories appropriately: <placeholder-1/>This requires a number of rules to be observed when writing multi-threaded programs using <application>gtkmm</application>. These are set out below, but one point to note is that extra care is required when deriving classes from <classname>sigc::trackable</classname>, because the effects are unintuitive (see particularly points 4 and 5 below).This section describes primarily what you can expect on a Linux system, when you use <ulink url="http://www.gnu.org/software/gdb/">the gdb debugger</ulink>.This section is simply a gathering of wisdom, general style guidelines and hints for creating <application>gtkmm</application> applications.This simple application draws a curve with Cairo and displays the control points for each end of the curve.This simple example shows how to load a <application>Glade</application> file at runtime and access the widgets with <application>Gtk::Builder</application>.This tells gmmproc that the C <function>*_new()</function> has a final GError** parameter which should be ignored.This variable must mention the correct library name, and this library name must be used to form the <varname>_SOURCES</varname>, <varname>_LDFLAGS</varname>, and <varname>_LIBADD</varname> variable names. It is permissible to use variables substituted by <filename>configure</filename> like <varname>@SOMETHINGMM_API_VERSION@</varname> as part of the variable names.TimeoutsTimeouts, I/O and Idle FunctionsTo access a widget, for instance to <methodname>show()</methodname> a dialog, use the <methodname>get_widget()</methodname> method, providing the widget's name. This name should be specified in the <application>Glade</application> Properties window. If the widget could not be found, or is of the wrong type, then the pointer will be set to 0. <placeholder-1/>To achieve this, you should use the normal <classname>Gtk::TreeView</classname><methodname>insert_column()</methodname> and <methodname>append_column()</methodname> methods, then use <methodname>get_column_cell_renderer()</methodname> to get the <classname>Gtk::CellRenderer</classname> used by that column.To add a new file to the list of recent documents, in the simplest case, you only need to provide the URI. For example:To add widgets to the action area, use the <methodname>add_action_widget()</methodname> method. They will be packed alongside the default buttons. Use the <methodname>remove_action_widget()</methodname> method to remove widgets.To begin our introduction to <application>gtkmm</application>, we'll start with the simplest program possible. This program will create an empty 200 x 200 pixel window.To change the selection, specify a <classname>Gtk::TreeModel::iterator</classname> or <classname>Gtk::TreeModel::Row</classname>, like so:To change the value shown, use the <methodname>set_fraction()</methodname> method, passing a <type>double</type> between 0.0 and 1.0 to provide the new percentage.To control which rows can be selected, use the <methodname>set_select_function()</methodname> method, providing a <classname>sigc::slot</classname> callback. For instance:To convince yourself that you've done well, you may wish to add a translation for a new locale. In order to do that, go to the <filename>po</filename> subdirectory of your project and execute the following command: <placeholder-1/>To define an accelerator key for keyboard navigation, place an underscore before one of the label's characters and specify <literal>true</literal> for the optional <literal>mnemonic</literal> parameter. For instance:To detect a click of the right mouse button, you need to handle the <literal>button_press_event</literal> signal, and check exactly which button was pressed. Because the <classname>TreeView</classname> normally handles this signal completely, you need to either override the default signal handler in a derived <classname>TreeView</classname> class, or use <methodname>connect_notify()</methodname> instead of <methodname>connect()</methodname>. You probably also want to call the default handler before doing anything else, so that the right-click will cause the row to be selected first.To determine the currently-visible page, use the <methodname>get_current_page()</methodname> method, and pass the result to <methodname>get_nth_page()</methodname>, which returns a pointer to the actual widget. To programmatically change the current page, use the <methodname>set_current_page()</methodname> method.To determine which key was pressed or released, you read the value of <varname>GdkEventKey::keyval</varname> and compare it with a constant in the <filename>&lt;gdk/gdkkeysyms.h&gt;</filename> header file. The states of modifier keys (shift, ctrl, etc.) are available as bit-flags in <varname>GdkEventKey::state</varname>.To discover the currently visible page, use the <methodname>get_current_page()</methodname> method. This returns the page number, and then calling <methodname>get_nth_page()</methodname> with that number will give you a pointer to the actual child widget.To discover what item, if any, the user has chosen from the ComboBox, call <methodname>ComboBox::get_active()</methodname>. This returns a <classname>TreeModel::iterator</classname> that you can dereference to a <classname>Row</classname> in order to read the values in your columns. For instance, you might read an integer ID value from the model, even though you have chosen only to show the human-readable description in the ComboBox. For instance:To do any drawing in <application>gtkmm</application> with Cairo, you must first create a <classname>Cairo::Context</classname> object. This class holds all of the graphics state parameters that describe how drawing is to be done. This includes information such as line width, color, the surface to draw to, and many other things. This allows the actual drawing functions to take fewer arguments to simplify the interface. In <application>gtkmm</application>, a <classname>Cairo::Context</classname> is created by calling the <methodname>Gdk::Window::create_cairo_context()</methodname> function. Since Cairo contexts are reference-counted objects, this function returns a <classname>Cairo::RefPtr&lt;Cairo::Context&gt;</classname> object.To do this, you need to call the <methodname>pulse()</methodname> method at regular intervals. You can also choose the step size, with the <methodname>set_pulse_step()</methodname> method.To draw an ellipse, you can scale the current transformation matrix by different amounts in the X and Y directions. For example, to draw an ellipse with center at <varname>x</varname>, <varname>y</varname> and size <varname>width</varname>, <varname>height</varname>: <placeholder-1/>To enable this functionality, you must create a <classname>EntryCompletion</classname> object, and provide it to the <classname>Entry</classname> widget via the <methodname>set_completion()</methodname> method.To find out what rows the user has selected, get the <classname>Gtk::TreeView::Selection</classname> object from the <classname>TreeView</classname>, like so:To find out what targets are currently available on the <classname>Clipboard</classname> for pasting, call the <methodname>request_targets()</methodname> method, specifying a method to be called with the information. For instance:To find out what type of signal handler you can connect to a signal, you can look it up in the reference documentation or the header file. Here's an example of a signal declaration you might see in the <application>gtkmm</application> headers:To force it to snap to the nearest <literal>step_increment</literal>, use <methodname>set_snap_to_ticks()</methodname>.To instantiate a <classname>Gtk::MenuBar</classname> or <classname>Gtk::Toolbar</classname> which you can actually show, you should use the <methodname>UIManager::get_widget()</methodname> method, and then add the widget to a container. For instance:To instantiate just one window, or just one of the child widgets, you can specify the name of a widget as the second parameter. For instance, <placeholder-1/>To look up recently used files, <classname>RecentManager</classname> provides several functions. To look up a specific item by its URI, you can use the <methodname>lookup_item()</methodname> function, which will return a <classname>RecentInfo</classname> class. If the specified URI did not exist in the list of recent files, <methodname>lookup_item()</methodname> throws a <classname>RecentManagerError</classname> exception. For example:To make the <classname>SpinButton</classname> 'wrap' between its upper and lower bounds, use the <methodname>set_wrap()</methodname> method.To obtain a <application>gtkmm</application> instance from a C GObject instance, use the Glib::wrap() function. For instanceTo pack widgets into a custom dialog, you should pack them into the <classname>Gtk::Box</classname>, available via <methodname>get_content_area()</methodname>. To just add a <classname>Button</classname> to the bottom of the <classname>Dialog</classname>, you could use the <methodname>add_button()</methodname> method.To prevent the user from typing non-numeric characters into the entry box, pass <literal>true</literal> to the <methodname>set_numeric()</methodname> method.To programmatically change the selected page, use the <methodname>set_current_page()</methodname> method.To receive the keyboard events, you must first call the <methodname>Gtk::Widget::add_events()</methodname> function with a bit mask of the events you're interested in. The event signal handler will receive an argument that depends on the type of event. For keyboard events it's a <type>GdkEventKey*</type>. As discribed in the <link linkend="sec-xeventsignals">appendix</link>, the event signal handler returns a <type>bool</type> value, to indicate that the signal is fully handled (<literal>true</literal>) or allow event propagation (<literal>false</literal>).To render more than one model column in a view column, you need to create the <classname>TreeView::Column</classname> widget manually, and use <methodname>pack_start()</methodname> to add the model columns to it.To respond to the user clicking on a row or range of rows, connect to the signal like so:To retrieve the state of the <classname>ToggleButton</classname>, you can use the <methodname>get_active()</methodname> method. This returns <literal>true</literal> if the button is "down". You can also set the toggle button's state, with <methodname>set_active()</methodname>. Note that, if you do this, and the state actually changes, it causes the "clicked" signal to be emitted. This is usually what you want.To see where the exception is thrown, you can use the <application>gdb</application> command <userinput>catch throw</userinput>. <placeholder-1/>To set the title of a page, use the <methodname>set_page_title()</methodname> method. The header and side images of a page can be set with the <methodname>set_page_header_image()</methodname> and <methodname>set_page_side_image()</methodname> methods.To set up <application>jhbuild</application>, follow the basic installation instructions from the <ulink url="http://developer.gnome.org/jhbuild/unstable/">jhbuild manual</ulink>. After you have installed <application>jhbuild</application>, you should copy the sample <application>jhbuild</application> configuration file into your home directory by executing the following command from the <application>jhbuild</application> directory: <screen>$ cp examples/sample.jhbuildrc ~/.jhbuildrc</screen>To show the popup menu, use <classname>Gtk::Menu</classname>'s <methodname>popup()</methodname> method, providing the button identifier and the time of activation, as provided by the <literal>button_press_event</literal> signal, which you will need to handle anyway. For instance:To simplify compilation, we use <literal>pkg-config</literal>, which is present in all (properly installed) <application>gtkmm</application> installations. This program 'knows' what compiler switches are needed to compile programs that use <application>gtkmm</application>. The <literal>--cflags</literal> option causes <literal>pkg-config</literal> to output a list of include directories for the compiler to look in; the <literal>--libs</literal> option requests the list of libraries for the compiler to link with and the directories to find them in. Try running it from your shell-prompt to see the results on your system.To specify that some text in the buffer should have specific formatting, you must define a tag to hold that formatting information, and then apply that tag to the region of text. For instance, to define the tag and its properties:To use a <application>gtkmm</application> instance with a C function that requires a C GObject instance, use the <function>gobj()</function> function to obtain a pointer to the underlying GObject instance. For instanceTo work around this, you could write a comment in the source code just before the string, telling the translators to use the special character if it is available in their languages. For english, you could then make an American English <filename>en_US.po</filename> translation which used that special character.Toggle buttonsToggleButtonToolItem ReferenceToolItemGroup ReferenceToolPaletteToolPalette ExampleToolPalette ReferenceTooltipTooltip ReferenceTooltipsTooltips are the little information windows that pop up when you leave your pointer over a widget for a few seconds. Use <methodname>set_tooltip_text()</methodname> to set a text string as a tooltip on any <classname>Widget</classname>. <classname>Gtk::ToolItem</classname>s are not <classname>Widget</classname>s, but have the same method for convenience. <classname>Gtk::Tooltip</classname> is used for more advanced tooltip usage, such as showing an image as well as text.TreeModel::iterator iter = refTreeSelection-&gt;get_selected();
if(iter) //If anything is selected
{
  TreeModel::Row row = *iter;
  //Do something with the row.
}TreeModelSort ReferenceTreeSortable ReferenceTreeStoreTreeStore, for a hierarchyTreeView - Drag And DropTreeView - Editable CellsTreeView - ListStoreTreeView - Popup Context MenuTreeView - TreeStoreTrolltech's Qt is the closest competition to <application>gtkmm</application>, so it deserves discussion.Try executing the example and increasing the system load. The upper progress bar will increase steadily; the lower one will slow down.Try to compile and run it before going on. You should see something like this:Two extra parameters are optional, for the case that the interface derives from another interface, which should be the case when the GInterface has another GInterface as a prerequisite. For instance, from <filename>loadableicon.hg</filename>: <placeholder-1/>Typically our wrapper library would be called libsomethingmm. We can start by copying the <ulink url="http://git.gnome.org/cgit/mm-common/tree/skeletonmm">skeleton source tree</ulink> from the mm-common module. <placeholder-1/>UI changes can be seen more quickly, so UIs are able to improve.UIManagerUnable to predeclare structsUnfortunately, the integration with the standard iostreams is not completely foolproof. <application>gtkmm</application> converts <classname>Glib::ustring</classname>s to a locale-specific encoding (which usually is not UTF-8) if you output them to an <classname>ostream</classname> with <function>operator&lt;&lt;</function>. Likewise, retrieving <classname>Glib::ustrings</classname> from <classname>istream</classname> with <function>operator&gt;&gt;</function> causes a conversion in the opposite direction. But this scheme breaks down if you go through a <classname>std::string</classname>, e.g. by inputting text from a stream to a <classname>std::string</classname> and then implicitly converting it to a <classname>Glib::ustring</classname>. If the string contained non-ASCII characters and the current locale is not UTF-8 encoded, the result is a corrupted <classname>Glib::ustring</classname>. You can work around this with a manual conversion. For instance, to retrieve the <classname>std::string</classname> from a <classname>ostringstream</classname>: <placeholder-1/>Unix and LinuxUnless your container is a top-level window that derives from <classname>Gtk::Window</classname>, you should probably also call <methodname>Gtk::Widget::set_has_window(false)</methodname> in your constructor. This means that your container does not create its own <classname>Gdk::Window</classname>, but uses its parent's window. (Note the difference between <classname>Gtk::Window</classname> and <classname>Gdk::Window</classname>.) If your container does need its own <classname>Gdk::Window</classname>, and does not derive from <classname>Gtk::Window</classname>, you must also override the <methodname>on_realize()</methodname> method as described in the <link linkend="sec-custom-widgets">Custom Widgets</link> section. And unless your container draws directly onto the underlying <classname>Gdk::Window</classname>, you should probably call <methodname>set_redraw_on_allocate(false)</methodname> to improve performance.Unlike the Windows UCS-2 Unicode solution, this does not require any special compiler options to process string literals, and it does not result in Unicode executables and libraries which are incompatible with ASCII ones.Unlike the other widgets in this section, pane widgets contain not one but two child widgets, one in each pane. Therefore, you should use <methodname>add1()</methodname> and <methodname>add2()</methodname> instead of the <methodname>add()</methodname> method.Unusual wordsUpdate PoliciesUpdate your <literal>DISTCLEANFILES</literal>: <placeholder-1/>Use <classname>Glib::Dispatcher</classname> to invoke <application>gtkmm</application> functions from worker threads (this is dealt with in more detail in the next section).Use <methodname>Gtk::Builder::get_widget_derived()</methodname> like so: <placeholder-1/>Use GNU <application>autoconf</application> and <application>automake</application>! They are your friends :) <application>Automake</application> examines C files, determines how they depend on each other, and generates a <filename>Makefile</filename> so the files can be compiled in the correct order. <application>Autoconf</application> permits automatic configuration of software installation, handling a large number of system quirks to increase portability.Use the <methodname>append_page()</methodname>, <methodname>prepend_page()</methodname> and <methodname>insert_page()</methodname> methods to add tabbed pages to the <literal>Notebook</literal>, supplying the child widget and the name for the tab.Use the <methodname>append_page()</methodname>, <methodname>prepend_page</methodname> and <methodname>insert_page()</methodname> methods to add pages to the <classname>Assistant</classname>, supplying the child widget for each page.Use the last GError** parameter of the C function to throw an exception.Use the last GError** parameter of the C virtual function (if there is one) to throw an exception.Use these macros if you're wrapping a simple struct or boxed type that provides direct access to its data members, to create getters and setters for the data members.Use these macros to automatically provide getters and setters for a data member that is a pointer type. For the getter function, it will create two methods, one const and one non-const.Use these macros to provide getters and setters for a data member that is a <classname>GObject</classname> type that must be referenced before being returned.Used in conjunction with the <literal>slot_name</literal> option to specify the name of the glue callback function that handles extracting the slot and then calling it. The address of this callback is also passed on to the C function that the method wraps.Useful methodsUsing Adjustments the Easy WayUsing Glib::DispatcherUsing a <application>gtkmm</application> widgetUsing a ModelUsing derived widgetsUsing non-ASCII characters in stringsUsing the git version of <application>gtkmm</application>VineWe also assume that you are using autotools (e.g. <application>automake</application> and <application>autoconf</application>) to build your project, and that you are using <ulink url="http://git.gnome.org/browse/gnome-common/tree/autogen.sh"><literal>./autogen.sh</literal> from <application>gnome-common</application></ulink>, which, among other things, takes care of some <application>intltool</application> initialization.We also discuss the <classname>Gtk::Paned</classname> widget, which allows you to divide a window into two separate "panes". This widget actually contains two child widgets, but the number is fixed so it seems appropriate.We just told you that the button's <literal>clicked</literal> signal is expecting to call a method with no arguments. All signals have requirements like this - you can't hook a function with two arguments to a signal expecting none (unless you use an adapter, such as <function>sigc::bind()</function>, of course). Therefore, it's important to know what type of signal handler you'll be expected to connect to a given signal.We made a new group by simply declaring a variable, <literal>group</literal>, of type <classname>Gtk::RadioButton::Group</classname>. Then we made three radio buttons, using a constructor to make each of them part of <literal>group</literal>.We make a call to <methodname>Cairo::Context::scale()</methodname>, passing in the width and height of the drawing area. This scales the user-space coordinate system such that the width and height of the widget are both equal to 1.0 'units'. There's no particular reason to scale the coordinate system in this case, but sometimes it can make drawing operations easier.We must mention all of our <filename>.hg</filename> and <filename>.ccg</filename> files in the <filename>skeleton/src/filelist.am</filename> file, typically in the <varname>files_hg</varname> variable.We now use std::vector in several methods instead of the intermediate *Handle types to make the API clearer.We should now create our first <filename>.hg</filename> and <filename>.ccg</filename> files, to wrap one of the objects in the C library. One pair of example source files already exists: <filename>skeleton.ccg</filename> and <filename>skeleton.hg</filename>. Create copies of these files as necessary.We then hook up a signal handler to <literal>m_button</literal>'s <literal>clicked</literal> signal. This prints our friendly greeting to <literal>stdout</literal>.We told <application>gtkmm</application> to put all three <classname>RadioButton</classname>s in the same group by obtaining the group with <methodname>get_group()</methodname> and using <methodname>set_group()</methodname> to tell the other <classname>RadioButton</classname>s to share that group.We will now explain each line of the exampleWe would very much like to hear of any problems you have learning <application>gtkmm</application> with this document, and would appreciate input regarding improvements. Please see the <link linkend="chapter-contributing">Contributing</link> section for further information.We're hooking it up to the <classname>Gtk::Button</classname> object called <varname>button</varname>.We've now learned enough to look at a real example. In accordance with an ancient tradition of computer science, we now introduce Hello World, a la <application>gtkmm</application>:What if a widget reconfigures the <parameter>upper</parameter> or <parameter>lower</parameter> fields of its <classname>Adjustment</classname>, such as when a user adds more text to a text widget? In this case, it emits the <literal>changed</literal> signal.What's the difference between spacing (set when the box is created) and padding (set when elements are packed)? Spacing is added between objects, and padding is added on either side of a widget. The following figure should make it clearer:When <varname>pixbuf</varname> goes out of scope an <methodname>unref()</methodname> will happen in the background and you don't need to worry about it anymore. There's no <literal>new</literal> so there's no <literal>delete</literal>.When a constructor must be partly hand written because, for instance, the <function>*_new()</function> C function's parameters do not correspond directly to object properties, or because the <function>*_new()</function> C function does more than call <function>g_object_new()</function>, the <function>_CONSTRUCT()</function> macro may be used in the .ccg file to save some work. The <function>_CONSTRUCT</function> macro takes a series of property names and values. For instance, from <filename>button.ccg</filename>: <placeholder-1/>When a drop destination has accepted a dragged item, certain signals will be emitted, depending on what action has been selected. For instance, the user might have held down the <keycap>Shift</keycap> key to specify a <literal>move</literal> rather than a <literal>copy</literal>. Remember that the user can only select the actions which you have specified in your calls to <methodname>drag_dest_set()</methodname> and <methodname>drag_source_set()</methodname>.When a program is aborted because of an unhandled C++ exception, it's sometimes possible to use a debugger to find the location where the exception was thrown. This is more difficult than usual if the exception was thrown from a signal handler.When deriving from <classname>Gtk::Container</classname>, you should override the following virtual methods: <placeholder-1/>When deriving from <classname>Gtk::Widget</classname>, you should override the following virtual methods. The methods marked (optional) need not be overridden in all custom widgets. The base class's methods may be appropriate. <placeholder-1/>When the Button emits its <literal>clicked</literal> signal, <methodname>on_button_clicked()</methodname> will be called.When the application runs, the <application>gettext</application> library checks the system-wide directory to see if there is a <filename>.mo</filename> file for the user's locale environment (you can set the locale with, for instance, "export LANG=de_DE.UTF-8" from a bash console). Later, when the program reaches a <literal>gettext</literal> call, it looks for a translation of a particular string. If none is found, the original string is used.When the mouse is over the button and a mouse button is pressed, <methodname>on_button_press()</methodname> will be called.When the user asks to copy some data, you should tell the <classname>Clipboard</classname> what targets are available, and provide the callback methods that it can use to get the data. At this point you should store a copy of the data, to be provided when the clipboard calls your callback method in response to a paste.When the user asks to paste data from the <classname>Clipboard</classname>, you should request a specific format and provide a callback method which will be called with the actual data. For instance:When the user enters arbitrary text, it may not be enough to connect to the <literal>changed</literal> signal, which is emitted for every typed character. It is not emitted when the user presses the Enter key. Pressing the Enter key or moving the keyboard focus to another widget may signal that the user has finished entering text. To be notified of these events, connect to the <classname>Entry</classname>'s <literal>activate</literal> and <literal>focus_out_event</literal> signals, like so <placeholder-1/> The <literal>changed</literal> signals of <classname>ComboBox</classname> and <classname>Entry</classname> are both emitted for every change. It doesn't matter which one you connect to. But only <classname>Entry</classname>'s <literal>focus_out_event</literal> signal is useful here.When using <function>_CLASS_GOBJECT()</function>, the constructors should be protected (rather than public) and each constructor should have a corresponding <function>_WRAP_CREATE()</function> in the public section. This prevents the class from being instantiated without using a <classname>RefPtr</classname>. For instance: <placeholder-1/>When using a <classname>Gtk::TreeStore</classname>, the rows can have child rows, which can have their own children in turn. Use <methodname>Gtk::TreeModel::Row::children()</methodname> to get the container of child <classname>Row</classname>s: <placeholder-1/>When using this simple <methodname>append_column()</methodname> override, the <classname>TreeView</classname> will display the model data with an appropriate <classname>CellRenderer</classname>. For instance, strings and numbers are shown in a simple <classname>Gtk::Entry</classname> widget, and booleans are shown in a <classname>Gtk::CheckButton</classname>. This is usually what you need. For other column types you must either connect a callback that converts your type into a string representation, with <methodname>TreeViewColumn::set_cell_data_func()</methodname>, or derive a custom <classname>CellRenderer</classname>. Note that (unsigned) short is not supported by default - You could use (unsigned) int or (unsigned) long as the column type instead.When you downloaded <application>jhbuild</application> from the git repository, you got a number of <filename>.modules</filename> files, specifying dependencies between modules. By default <application>jhbuild</application> does not use the downloaded versions of these files, but reads the latest versions in the git repository. This is usually what you want. If you don't want it, use the <varname>use_local_modulesets</varname> variable in <filename>.jhbuildrc</filename>.When you select a choice from the drop-down menu, the value from this column will be placed in the <classname>Entry</classname>.When you write in the entry, a key release event will be emitted, which will go first to the toplevel window (<classname>Gtk::Window</classname>), since we have one event handler set to be called before, that's what is called first (<methodname>windowKeyReleaseBefore()</methodname>). Then the default handler is called (which we have overridden), and after that the event is sent to the widget that has focus, the <classname>Entry</classname> in our example and, depending on whether we let it propagate, it can reach the <classname>Grid</classname>'s and the <classname>Window</classname>'s event handlers. If it propagates, the text you're writing will appear in the <classname>Label</classname> above the <classname>Entry</classname>.Whenever you press or release a key, an event is emitted. You can connect a signal handler to handle such events.Why use <application>gtkmm</application> instead of GTK+?Widget ReferenceWidget::on_expose_event() was replaced by Widget::on_draw(), which assumes that cairomm is used for drawing, via the provided <classname>Cairo::Context</classname> and does not require you to call <methodname>Cairo::Context::clip()</methodname>.WidgetsWidgets Without X-WindowsWidgets and ChildAnchorsWidgets are arranged inside container widgets such as frames and notebooks, in a hierarchy of widgets within widgets. Some of these container widgets, such as <classname>Gtk::Grid</classname>, are not visible - they exist only to arrange other widgets. Here is some example code that adds 2 <classname>Gtk::Button</classname> widgets to a <classname>Gtk::Box</classname> container widget: <placeholder-1/> and here is how to add the <classname>Gtk::Box</classname>, containing those buttons, to a <classname>Gtk::Frame</classname>, which has a visible frame and title: <placeholder-2/>With <function>_WRAP_METHOD()</function> it is also possible for the return of the wrapped C function (if it has one) to be placed in an output parameter of the C++ method instead of having the C++ method also return a value like the C function does. To do that, simply include the output parameter in the C++ method parameter list appending a <literal>{OUT}</literal> to the output parameter name. For example, if <function>gtk_widget_get_request_mode()</function> is declared as the following: <placeholder-1/> And having the C++ method set an output parameter is desired instead of returning a <type>SizeRequestMode</type>, something like the following could be used: <placeholder-2/> The <literal>{OUT}</literal> appended to the name of the <parameter>mode</parameter> output parameter tells <command>gmmproc</command> to place the return of the C function in that output parameter. In this case, however, a necessary initialization macro like the following would also have to be specified: <placeholder-3/> Which could also be written as: <placeholder-4/>With Cairo, the same function is used to draw arcs, circles, or ellipses: <methodname>Cairo::Context::arc()</methodname>. This function takes five arguments. The first two are the coordinates of the center point of the arc, the third argument is the radius of the arc, and the final two arguments define the start and end angle of the arc. All angles are defined in radians, so drawing a circle is the same as drawing an arc from 0 to 2 * M_PI radians. An angle of 0 is in the direction of the positive X axis (in user-space). An angle of M_PI/2 radians (90 degrees) is in the direction of the positive Y axis (in user-space). Angles increase in the direction from the positive X axis toward the positive Y axis. So with the default transformation matrix, angles increase in a clockwise direction. (Remember that the positive Y axis points downwards.)Working with gtkmm's Source CodeWrapping <classname>GList*</classname> and <classname>GSList*</classname> parameters: First, you need to discover what objects are contained in the list's data field for each item, usually by reading the documentation for the C function. The list can then be wrapped by a <classname>std::vector</classname> type. For instance, <code>std::vector&lt; Glib::RefPtr&lt;Gdk::Pixbuf&gt; &gt;</code>. You may need to define a Traits type to specify how the C and C++ types should be converted.Wrapping <classname>GList*</classname> and <classname>GSList*</classname> return types: You must discover whether the caller should free the list and whether it should release the items in the list, again by reading the documentation of the C function. With this information you can choose the ownership (none, shallow or deep) for the m4 conversion rule, which you should probably put directly into the .hg file because the ownership depends on the function rather than the type. For instance: <placeholder-1/>Wrapping C Libraries with gmmprocWriting signal handlersWriting the vfuncs .defsX Event signalsX events are described in more detail in the <link linkend="sec-xeventsignals">X Event signals</link> section in the appendix.X events differ in some ways from other signals. These differences are described in the <link linkend="sec-xeventsignals">X Event signals</link> section in the appendix. Here we will use keyboard events to show how X events can be used in a program.Yes, that's correct: a Window can contain at most one widget. How, then, can we use a window for anything useful? By placing a multiple-child container in the window. The most useful container widgets are <classname>Gtk::Grid</classname> and <classname>Gtk::Box</classname>.You are likely to encounter some problems in the library that you are wrapping, particularly if it is a new project. Here are some common problems, with solutions.You are not guaranteed to get the <literal>Gtk::SizeRequestMode</literal> that you request. Therefore all four of the <methodname>get_preferred_xxx_vfunc()</methodname> methods must return sensible values.You can adjust the position of the divider using the <methodname>set_position()</methodname> method, and you will probably need to do so.You can also cast to a derived type, but the syntax is a little different than with a normal pointer.You can also connect to <classname>CellRenderer</classname> signals to detect user actions. For instance:You can also specify a signal handler when calling <methodname>ActionGroup::add()</methodname>. This signal handler will be called when the action is activated via either a menu item or a toolbar button.You can also use <methodname>get_tag_table()</methodname> to get, and maybe modify, the <classname>TextBuffer</classname>'s default <classname>TagTable</classname> instead of creating one explicitly.You can apply more than one <classname>Tag</classname> to the same text, by using <methodname>apply_tag()</methodname> more than once, or by using <methodname>insert_with_tags()</methodname>. The <classname>Tag</classname>s might specify different values for the same properties, but you can resolve these conflicts by using <methodname>Tag::set_priority()</methodname>.You can build several modules by setting the <varname>modules</varname> variable to a meta-package, e.g. <literal>meta-gnome-core</literal>, or listing more than one module name. The <varname>modules</varname> variable specifies which modules will be built when you don't explicitly specify anything on the command line. You can always build a different moduleset later by specifying it on the commandline (e.g. <command>jhbuild build gtkmm</command>).You can cast <classname>RefPtr</classname>s to base types, just like normal pointers.You can copy <classname>RefPtr</classname>s, just like normal pointers. But unlike normal pointers, you don't need to worry about deleting the underlying instance.You can create a new <classname>RecentManager</classname>, but you'll most likely just want to use the default one. You can get a reference to the default <classname>RecentManager</classname> with <methodname>get_default()</methodname>.You can dereference a smartpointer with the -&gt; operator, to call the methods of the underlying instance, just like a normal pointer.You can dereference the iterator to get the Row:You can draw very sophisticated shapes using Cairo, but the methods to do so are quite basic. Cairo provides methods for drawing straight lines, curved lines, and arcs (including circles). These basic shapes can be combined to create more complex shapes and paths which can be filled with solid colors, gradients, patterns, and other things. In addition, Cairo can perform complex transformations, do compositing of images, and render antialiased text.You can embed widgets, such as <classname>Gtk::Button</classname>s, in the text. Each such child widget needs a <classname>ChildAnchor</classname>. ChildAnchors are associated with <classname>iterators</classname>. For instance, to create a child anchor at a particular position, use <methodname>Gtk::TextBuffer::create_child_anchor()</methodname>:You can modify the update policy using the <methodname>set_update_policy()</methodname> method, specifying either <literal>Gtk::UPDATE_ALWAYS</literal> or <literal>Gtk::UPDATE_IF_VALID</literal>. <literal>Gtk::UPDATE_ALWAYS</literal> causes the <classname>SpinButton</classname> to ignore errors encountered while converting the text in the entry box to a numeric value. This setting also therefore allows the <classname>SpinButton</classname> to accept non-numeric values. You can force an immediate update using the <methodname>update()</methodname> method.You can set the <emphasis>margin</emphasis> and <emphasis>expand</emphasis> properties of the child <classname>Widget</classname>s to control their spacing and their behaviour when the Grid is resized.You can set the spinbutton's value using the <methodname>set_value()</methodname> method, and retrieve it with <methodname>get_value()</methodname>.You can specify a <classname>Gtk::TreeModel</classname> when constructing the <classname>Gtk::TreeView</classname>, or you can use the <methodname>set_model()</methodname> method, like so:You can specify a name for the <classname>Tag</classname> when using the <methodname>create()</methodname> method, but it is not necessary.You can stop the timeout method by returning <literal>false</literal> from your signal handler. Therefore, if you want your method to be called repeatedly, it should return <literal>true</literal>.You can then connect to the appropriate "edited" signal. For instance, connect to <methodname>Gtk::CellRendererText::signal_edited()</methodname>, or <methodname>Gtk::CellRendererToggle::signal_toggled()</methodname>. If the column contains more than one <classname>CellRenderer</classname> then you will need to use <methodname>Gtk::TreeView::get_column()</methodname> and then call <methodname>get_cell_renderers()</methodname> on that view Column.You can then connect to the signal using the same syntax used when connecting to <application>gtkmm</application> signals. For instance, <placeholder-1/>You can then use the <methodname>get_iter()</methodname> method later to create an iterator for the <classname>Mark</classname>'s new position.You can use <application>Glade</application> to layout your own custom widgets derived from <application>gtkmm</application> widget classes. This keeps your code organized and encapsulated. Of course you won't see the exact appearance and properties of your derived widget in <application>Glade</application>, but you can specify its location and child widgets and the properties of its <application>gtkmm</application> base class.You can use C APIs which do not yet have convenient C++ interfaces. It is generally not a problem to use C APIs from C++, and <application>gtkmm</application> helps by providing access to the underlying C object, and providing an easy way to create a C++ wrapper object from a C object, provided that the C API is also based on the GObject system.You can use the <methodname>append_column()</methodname> method to tell the View that it should display certain Model columns, in a certain order, with a certain column title.You can use the <methodname>operator[]</methodname> override to get the data in a particular column in a row, specifiying the <classname>TreeModelColumn</classname> used to create the model.You can use the <methodname>operator[]</methodname> override to set the data for a particular column in the row, specifying the <classname>TreeModelColumn</classname> used to create the model.You can use the <methodname>toggled()</methodname> method to toggle the button, rather than forcing it to be up or down: This switches the button's state, and causes the <literal>toggled</literal> signal to be emitted.You can usually pretend that <classname>Gtk::Clipboard</classname> is a singleton. You can get the default clipboard instance with <methodname>Gtk::Clipboard::get()</methodname>. This is probably the only clipboard you will ever need.You could just declare that signal as a public member variable, but some people find that distasteful and prefer to make it available via an accessor method, like so: <placeholder-1/>You could then encapsulate the manipulation of the child widgets in the constructor of the derived class, maybe using <methodname>get_widget()</methodname> or <methodname>get_widget_derived()</methodname> again. For instance, <placeholder-1/>You don't always need to call the parent's method; there are times when you might not want to. Note that we called the parent method <emphasis>after</emphasis> writing "Hello World", but we could have called it before. In this simple example, it hardly matters much, but there are times when it will. With signals, it's not quite so easy to change details like this, and you can do something here which you can't do at all with connected signal handlers: you can call the parent method in the <emphasis>middle</emphasis> of your custom code.You have no way of getting a bare <classname>Gdk::Pixbuf</classname>. In the example, <varname>pixbuf</varname> is a smart pointer, so you can do this, much like a normal pointer: <placeholder-1/>You may add a custom tab to the print dialog: <placeholder-1/>You may be wondering how to make <application>gtkmm</application> do useful work while it's idling along. Happily, you have several options. Using the following methods you can create a timeout method that will be called every few milliseconds.You might also derive non-widget classes from Gtk::Object so they can be used without <classname>Glib::RefPtr</classname>. For instance, they could then be instantiated with <function>Gtk::manage()</function> or on the stack as a member variable. This is convenient, but you should use this only when you are sure that true reference-counting is not needed. We consider it useful for widgets.You might be surprised to learn that <application>gtkmm</application> doesn't use <classname>std::string</classname> in its interfaces. Instead it uses <classname>Glib::ustring</classname>, which is so similar and unobtrusive that you could actually pretend that each <classname>Glib::ustring</classname> is a <classname>std::string</classname> and ignore the rest of this section. But read on if you want to use languages other than English in your application.You might need to react to every change of selection in the ComboBox, for instance to update other widgets. To do so, you should handle the <literal>changed</literal> signal. For instance:You might not anticipate the need to support additional languages, but you can never rule it out. And it's easier to develop the application properly in the first place rather than retrofitting later.You might occasionally find it useful to handle X events when there's something you can't accomplish with normal signals. <classname>Gtk::Button</classname>, for example, does not send mouse-pointer coordinates with its <literal>clicked</literal> signal, but you could handle <literal>button_press_event</literal> if you needed this information. X events are also often used to handle key-presses.You might then handle the <classname>ToolButton</classname>'s <literal>clicked</literal> signal. Alternatively, you could allow the item to be dragged to another widget, by calling <methodname>Gtk::ToolPalette::add_drag_dest()</methodname> and then using <methodname>Gtk::ToolPalette::get_drag_item()</methodname> in the other widget's <literal>drag_data_received</literal> signal handler.You might want to associate extra data with each row. If so, just add it as a Model column, but don't add it to the View.You might want to be notified whenever the user types in a text entry widget. <classname>Gtk::Entry</classname> provides two signals, <literal>activate</literal> and <literal>changed</literal>, for this purpose. <literal>activate</literal> is emitted when the user presses the Enter key in a text-entry widget; <literal>changed</literal> is emitted when the text in the widget changes. You can use these, for instance, to validate or filter the text the user types. Moving the keyboard focus to another widget may also signal that the user has finished entering text. The <literal>focus_out_event</literal> signal that <classname>Gtk::Entry</classname> inherits from <classname>Gtk::Widget</classname> can notify you when that happens. The <link linkend="sec-comboboxentry">ComboBox with an Entry</link> section contains example programs that use these signals.You might want to include additional source files that will not be generated by <command>gmmproc</command> from <filename>.hg</filename> and <filename>.ccg</filename> files. You can simply place these in your <filename>libsomething/libsomethingmm</filename> directory and mention them in the <filename>Makefile.am</filename> in the <varname>files_extra_h</varname> and <varname>files_extra_cc</varname> variables.You might wish to reuse documentation that exists for the C library that you are wrapping. GTK-style C libraries typically use gtk-doc and therefore have source code comments formatted for gtk-doc and some extra documentation in .sgml and .xml files. The docextract_to_xml.py script, from glibmm's <filename>tools/defs_gen</filename> directory, can read these files and generate an .xml file that <command>gmmproc</command> can use to generate doxygen comments. <command>gmmproc</command> will even try to transform the documentation to make it more appropriate for a C++ API.You must call the base class's constructor in the initialization list, providing the C pointer. For instance, <placeholder-1/>You must edit the source code of your own <filename>generate_extra_defs</filename> tool in order to generate the <filename>.defs</filename> for the GObject C types that you wish to wrap. In the skeleton source tree, the source file is named <filename>codegen/extradefs/generate_extra_defs_skeleton.cc</filename>. If not done so already, the file should be renamed, with the basename of your new binding substituted for the <varname>skeleton</varname> placeholder. The <filename>codegen/Makefile.am</filename> file should also mention the new source filename.You must set the optional parameter <literal>after = false</literal> in the call to <literal>signal_command_line().connect()</literal>, because your signal handler must be called before the default signal handler. You must also call <methodname>Gio::Application::activate()</methodname> in the signal handler, unless you want your application to exit without showing its main window. (<classname>Gio::Application</classname> is a base class of <classname>Gtk::Application</classname>.)You need to specify the <classname>Alignment</classname>'s characteristics to the constructor, or to the <methodname>set()</methodname> method. In particular, you won't notice much effect unless you specify a number other than 1.0 for the <literal>xscale</literal> and <literal>yscale</literal> parameters, because 1.0 simply means that the child widget will expand to fill all available space.You never know how much space a string will take on screen when translated. It might very possibly be twice the size of the original English string. Luckily, most <application>gtkmm</application> widgets will expand at runtime to the required size.You probably won't ever need to attach a handler to this signal, unless you're writing a new type of range widget.You should avoid C-style pointer arithmetic, and functions such as strlen(). In UTF-8, each character might need anywhere from 1 to 6 bytes, so it's not possible to assume that the next byte is another character. <classname>Glib::ustring</classname> worries about the details of this for you so you can use methods such as Glib::ustring::substr() while still thinking in terms of characters instead of bytes.You should avoid cryptic abbreviations, slang, or jargon. They are usually difficult to translate, and are often difficult for even native speakers to understand. For instance, prefer "application" to "app"You should avoid including the C header from your C++ header, to avoid polluting the global namespace, and to avoid exporting unnecessary public API. But you will need to include the necessary C headers from your .ccg file.You should be very careful when installing to standard system prefixes such as <filename>/usr</filename>. Linux distributions install software packages to <filename>/usr</filename>, so installing a source package to this prefix could corrupt or conflict with software installed using your distribution's package-management system. Ideally, you should use a separate prefix for all software you install from source.You should not declare these types yourself. You should instead use whatever Standard C++ container you prefer. glibmm will do the conversion for you. Here are some of these intermediate types: <placeholder-1/>You should save the chosen <classname>Gtk::PageSetup</classname> so you can use it again if the page setup dialog is shown again.You should then cast that <classname>Gtk::CellRenderer*</classname> to the specific <classname>CellRenderer</classname> that you expect, so you can use specific API.You specify the <classname>ColumnRecord</classname> when creating the Model, like so:You still need C++ code to deal with User Interface changes triggered by user actions, but using <application>Gtk::Builder</application> for the widget layout allows you to focus on implementing that functionality.You will typically use this macro when the class already derives from Gtk::Object. For instance, you will use it when wrapping a GTK+ Widget, because Gtk::Widget derives from Gtk::Object.You've probably noticed that <application>gtkmm</application> windows seem "elastic" - they can usually be stretched in many different ways. This is due to the <emphasis>widget packing</emphasis> system.Your application doesn't need to wait for clipboard operations, particularly between the time when the user chooses Copy and then later chooses Paste. Most <classname>Gtk::Clipboard</classname> methods take <classname>sigc::slot</classname>s which specify callback methods. When <classname>Gtk::Clipboard</classname> is ready, it will call these methods, either providing the requested data, or asking for data.Your callback will then provide the stored data when the user chooses to paste the data. For instance:Your derived class must have a constructor that takes a pointer to the underlying C type, and the <classname>Gtk::Builder</classname> instance. All relevant classes of <application>gtkmm</application> typedef their underlying C type as <classname>BaseObjectType</classname> (<classname>Gtk::Dialog</classname> typedefs <classname>BaseObjectType</classname> as <type>GtkDialog</type>, for instance).Your existing knowledge of C++ will help you with <application>gtkmm</application> as it would with any library. Unless we state otherwise, you can expect <application>gtkmm</application> classes to behave like any other C++ class, and you can expect to use your existing C++ techniques with <application>gtkmm</application> classes.Your implementation of the <methodname>child_type_vfunc()</methodname> method should report the type of widget that may be added to your container, if it is not yet full. This is usually <methodname>Gtk::Widget::get_type()</methodname> to indicate that the container may contain any class derived from <classname>Gtk::Widget</classname>. If the container may not contain any more widgets, then this method should return <literal>G_TYPE_NONE</literal>.Your library must be initialized before it can be used, to register the new types that it makes available. Also, the C library that you are wrapping might have its own initialization function that you should call. You can do this in an <function>init()</function> function that you can place in hand-coded <filename>init.h</filename> and <filename>init.cc</filename> files. This function should initialize your dependencies (such as the C function, and <application>gtkmm</application>) and call your generated <function>wrap_init()</function> function. For instance: <placeholder-1/>_CLASS_BOXEDTYPE_CLASS_BOXEDTYPE( C++ class, C class, new function, copy function, free function )_CLASS_BOXEDTYPE_STATIC_CLASS_BOXEDTYPE_STATIC( C++ class, C class )_CLASS_GENERIC_CLASS_GENERIC( C++ class, C class )_CLASS_GOBJECT_CLASS_GOBJECT( C++ class, C class, C casting macro, C++ base class, C base class )_CLASS_GTKOBJECT_CLASS_GTKOBJECT( C++ class, C class, C casting macro, C++ base class, C base class )_CLASS_GTKOBJECT()_CLASS_INTERFACE_CLASS_INTERFACE( C++ class, C class, C casting macro, C interface struct, Base C++ class (optional), Base C class (optional) )_CLASS_OPAQUE_COPYABLE_CLASS_OPAQUE_COPYABLE( C++ class, C class, new function, copy function, free function )_CLASS_OPAQUE_REFCOUNTED_CLASS_OPAQUE_REFCOUNTED( C++ class, C class, new function, ref function, unref function )_CTOR_DEFAULT_DEFS()_IGNORE / _IGNORE_SIGNAL_IGNORE(C function name 1, C function name2, etc)_IGNORE_SIGNAL(C signal name 1, C signal name2, etc)_IMPLEMENTS_INTERFACE_IMPLEMENTS_INTERFACE()_IMPLEMENTS_INTERFACE(C++ interface name)_MEMBER_GET / _MEMBER_SET_MEMBER_GET(C++ name, C name, C++ type, C type)_MEMBER_GET(x, x, int, int)_MEMBER_GET_GOBJECT / _MEMBER_SET_GOBJECT_MEMBER_GET_GOBJECT(C++ name, C name, C++ type, C type)_MEMBER_GET_PTR / _MEMBER_SET_PTR_MEMBER_GET_PTR(C++ name, C name, C++ type, C type)_MEMBER_SET(C++ name, C name, C++ type, C type)_MEMBER_SET_GOBJECT(C++ name, C name, C++ type, C type)_MEMBER_SET_PTR(C++ name, C name, C++ type, C type)_PINCLUDE()_WRAP_CTOR_WRAP_ENUM_WRAP_ENUM_DOCS_ONLY_WRAP_GERROR_WRAP_METHOD_WRAP_METHOD( C++ method signature, C function name)_WRAP_METHOD_DOCS_ONLY_WRAP_METHOD_DOCS_ONLY(C function name)_WRAP_PROPERTY_WRAP_PROPERTY(C property name, C++ type)_WRAP_SIGNAL_WRAP_SIGNAL( C++ signal handler signature, C signal name)_WRAP_VFUNC_WRAP_VFUNC( C++ method signature, C function name)adj-&gt;signal_value_changed().connect(sigc::bind&lt;MyPicture*&gt;(sigc::mem_fun(*this,
    &amp;cb_rotate_picture), picture));adjustment-&gt;signal_changed();and connect it to the scale widget's adjustment like this:and thenatkmmbinding_namebindtextdomain(GETTEXT_PACKAGE, PROGRAMNAME_LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);boolbool DemoWindow::select_function(
    const Glib::RefPtr&lt;Gtk::TreeModel&gt;&amp; model,
    const Gtk::TreeModel::Path&amp; path, bool)
{
  const Gtk::TreeModel::iterator iter = model-&gt;get_iter(path);
  return iter-&gt;children().empty(); // only allow leaf nodes to be selected
}bool ExampleWindow::on_button_press_event(GdkEventButton* event)
{
  if( (event-&gt;type == GDK_BUTTON_PRESS) &amp;&amp;
      (event-&gt;button == 3) )
  {
    m_Menu_Popup-&gt;popup(event-&gt;button, event-&gt;time);
    return true; //It has been handled.
  }
  else
    return false;
}bool MyArea::on_draw(const Cairo::RefPtr&lt;Cairo::Context&gt;&amp; cr)
{
  Glib::RefPtr&lt;Gdk::Pixbuf&gt; image = Gdk::Pixbuf::create_from_file("myimage.png");
  // Draw the image at 110, 90, except for the outermost 10 pixels.
  Gdk::Cairo::set_source_pixbuf(cr, image, 100, 80);
  cr-&gt;rectangle(110, 90, image-&gt;get_width()-20, image-&gt;get_height()-20);
  cr-&gt;fill();
  return true;
}buttons examplecairocairommcell.property_editable() = true;class HelloWorld : public Gtk::Window
{

public:
  HelloWorld();
  virtual ~HelloWorld();

protected:
  //Signal handlers:
  virtual void on_button_clicked();

  //Member widgets:
  Gtk::Button m_button;
};class ModelColumns : public Gtk::TreeModelColumnRecord
{
public:

  ModelColumns()
    { add(m_col_text); add(m_col_number); }

  Gtk::TreeModelColumn&lt;Glib::ustring&gt; m_col_text;
  Gtk::TreeModelColumn&lt;int&gt; m_col_number;
};

ModelColumns m_Columns;class RadioButtons : public Gtk::Window
{
public:
    RadioButtons();

protected:
    Gtk::RadioButton m_rb1, m_rb2, m_rb3;
};

RadioButtons::RadioButtons()
  : m_rb1("button1"),
    m_rb2("button2"),
    m_rb3("button3")
{
    Gtk::RadioButton::Group group = m_rb1.get_group();
    m_rb2.set_group(group);
    m_rb3.set_group(group);
}class RadioButtons : public Gtk::Window
{
public:
    RadioButtons();
};

RadioButtons::RadioButtons()
{
    Gtk::RadioButton::Group group;
    Gtk::RadioButton *m_rb1 = Gtk::manage(
      new Gtk::RadioButton(group,"button1"));
    Gtk::RadioButton *m_rb2 = manage(
      new Gtk::RadioButton(group,"button2"));
      Gtk::RadioButton *m_rb3 = manage(
        new Gtk::RadioButton(group,"button3"));
}clickedconfigure.acconstversioncontext-&gt;save();
context-&gt;translate(x, y);
context-&gt;scale(width / 2.0, height / 2.0);
context-&gt;arc(0.0, 0.0, 1.0, 0.0, 2 * M_PI);
context-&gt;restore();custom_c_callbackcustom_default_handlercustom_vfunccustom_vfunc_callbackdeprecateddisplay_message("Getting ready for i18n.");display_message(_("Getting ready for i18n."));doubleenterenumserrthrowevent_box.add(child_widget);flags: Used only for drag and drop, this specifies whether the data may be dragged to other widgets and applications, or only to the same ones.functionsg++ simple.cc -o simple `pkg-config gtkmm-3.0 --cflags --libs`gbooleangchar*gdk-pixbufgdoublegettext manualgintglibglibmmgmmproc Parameter Processinggnomemm_hellogtk.defsgtk_enums.defsgtk_methods.defsgtk_signals.defsgtk_vfuncs.defsgtkmmgtkmm-3.0 is the name of the current stable API. There was an older API called gtkmm-2-4 which installs in parallel when it is available. There were several versions of gtkmm-2.4, such as gtkmm 2.10 and there are several versions of the gtkmm-3.0 API. Note that the API name does not change for every version because that would be an incompatible API and ABI break. Theoretically, there might be a future gtkmm-4.0 API which would install in parallel with gtkmm-3.0 without affecting existing applications.gtkmm_helloguintgunicharifdefinfo: An identifier which will be sent to your signals to tell you which TargetEntry was used.intint cols_count = m_TreeView.append_column_editable("Alex", m_columns.alex);
Gtk::TreeViewColumn* pColumn = m_TreeView.get_column(cols_count-1);
if(pColumn)
{
  Gtk::CellRendererToggle* pRenderer =
    static_cast&lt;Gtk::CellRendererToggle*&gt;(pColumn-&gt;get_first_cell());
  pColumn-&gt;add_attribute(pRenderer-&gt;property_visible(), m_columns.visible);
  pColumn-&gt;add_attribute(pRenderer-&gt;property_activatable(), m_columns.world);int main(int argc, char** argv)
{
  Glib::RefPtr&lt;Gtk::Application&gt; app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  HelloWorld helloworld;
  return app-&gt;run(helloworld);
}intltool-update --potleavelib_LTLIBRARIESlibsigc++ 2.0m4 Conversionsm4 Initializationsm_TextView.add_child_at_anchor(m_Button, refAnchor);m_TreeView.append_column("Messages", m_Columns.m_col_text);m_TreeView.set_model(m_refListStore);m_box.pack_start(m_Button1);
m_box.pack_start(m_Button2);m_button1.signal_clicked().connect( sigc::mem_fun(*this,
  &amp;HelloWorld::on_button_clicked) );m_combo.set_entry_text_column(m_columns.m_col_name);m_combo.signal_changed().connect( sigc::mem_fun(*this,
      &amp;ExampleWindow::on_combo_changed) );m_frame.add(m_box);m_rb2.set_group(m_rb1.get_group()); //doesn't workm_refActionGroup = Gtk::ActionGroup::create();

m_refActionGroup-&gt;add( Gtk::Action::create("MenuFile", "_File") );
m_refActionGroup-&gt;add( Gtk::Action::create("New", "_New"),
  sigc::mem_fun(*this, &amp;ExampleWindow::on_action_file_new) );
m_refActionGroup-&gt;add( Gtk::Action::create("ExportData", "Export Data"),
  sigc::mem_fun(*this, &amp;ExampleWindow::on_action_file_open) );
m_refActionGroup-&gt;add( Gtk::Action::create("Quit", "_Quit"),
  sigc::mem_fun(*this, &amp;ExampleWindow::on_action_file_quit) );m_refTreeSelection-&gt;set_select_function( sigc::mem_fun(*this,
    &amp;DemoWindow::select_function) );modules = [ 'gtkmm' ]moduleset = 'gnome-suites-core-deps-3.12'no_default_handlerno_slot_copyobjects (GObjects, widgets, interfaces, boxed-types and plain structs)orpangommpkg-configpressedpropertiesrefBuffer-&gt;apply_tag(refTagMatch, iterRangeStart, iterRangeStop);refBuffer-&gt;insert_with_tag(iter, "Some text", refTagMatch);refClipboard-&gt;request_contents("example_custom_target",
    sigc::mem_fun(*this, &amp;ExampleWindow::on_clipboard_received) );refClipboard-&gt;request_targets( sigc::mem_fun(*this,
    &amp;ExampleWindow::on_clipboard_received_targets) );refTreeSelection-&gt;selected_foreach_iter(
    sigc::mem_fun(*this, &amp;TheClass::selected_row_callback) );

void TheClass::selected_row_callback(
    const Gtk::TreeModel::iterator&amp; iter)
{
  TreeModel::Row row = *iter;
  //Do something with the row.
}refTreeSelection-&gt;set_mode(Gtk::SELECTION_MULTIPLE);refTreeSelection-&gt;signal_changed().connect(
    sigc::mem_fun(*this, &amp;Example_IconTheme::on_selection_changed)
);refreturnrefreturn_ctypereleasedreturn app-&gt;run(window);row[m_Columns.m_col_text] = "sometext";signalsslot_callbackslot_namesrc/main.cc
src/other.ccstd::cout &lt;&lt; Glib::ustring::compose(
             _("Current amount: %1 Future: %2"), amount, future) &lt;&lt; std::endl;

label.set_text(Glib::ustring::compose(_("Really delete %1 now?"), filename));std::cout &lt;&lt; _("Current amount: ") &lt;&lt; amount
          &lt;&lt; _(" Future: ") &lt;&lt; future &lt;&lt; std::endl;

label.set_text(_("Really delete ") + filename + _(" now?"));std::ostringstream output;
output.imbue(std::locale("")); // use the user's locale for this stream
output &lt;&lt; percentage &lt;&lt; " % done";
label-&gt;set_text(Glib::locale_to_utf8(output.str()));std::stringstd::string uses 8 bit per character, but 8 bits aren't enough to encode languages such as Arabic, Chinese, and Japanese. Although the encodings for these languages have now been specified by the Unicode Consortium, the C and C++ languages do not yet provide any standardised Unicode support. GTK+ and GNOME chose to implement Unicode using UTF-8, and that's what is wrapped by Glib::ustring. It provides almost exactly the same interface as std::string, along with automatic conversions to and from std::string.std::vector&lt; Glib::RefPtr&lt;Gtk::RecentInfo&gt; &gt; info_list = recent_manager-&gt;get_items();target: A name, such as "STRING"translator-creditstypedef Gtk::TreeModel::Children type_children; //minimise code length.
type_children children = refModel-&gt;children();
for(type_children::iterator iter = children.begin();
    iter != children.end(); ++iter)
{
  Gtk::TreeModel::Row row = *iter;
  //Do something with the row - see above for set/get.
}vfuncsvfuncs (function pointer member fields in structs), written by hand.void ExampleWindow::on_button_delete()
{
  Glib::RefPtr&lt;Gtk::TreeSelection&gt; refTreeSelection =
      m_treeview.get_selection();
  if(refTreeSelection)
  {
    Gtk::TreeModel::iterator sorted_iter =
        m_refTreeSelection-&gt;get_selected();
    if(sorted_iter)
    {
      Gtk::TreeModel::iterator iter =
          m_refModelSort-&gt;convert_iter_to_child_iter(sorted_iter);
      m_refModel-&gt;erase(iter);
    }
  }
}void ExampleWindow::on_clipboard_get(
    Gtk::SelectionData&amp; selection_data, guint /* info */)
{
  const std::string target = selection_data.get_target();

  if(target == "example_custom_target")
    selection_data.set("example_custom_target", m_ClipboardStore);
}void ExampleWindow::on_clipboard_received(
    const Gtk::SelectionData&amp; selection_data)
{
  Glib::ustring clipboard_data = selection_data.get_data_as_string();
  //Do something with the pasted data.
}void ExampleWindow::on_clipboard_received_targets(
  const std::vector&lt;Glib::ustring&gt;&amp; targets)
{
  const bool bPasteIsPossible =
    std::find(targets.begin(), targets.end(),
      example_target_custom) != targets.end();

  // Enable/Disable the Paste button appropriately:
  m_Button_Paste.set_sensitive(bPasteIsPossible);
}void cb_rotate_picture (MyPicture* picture)
{
  picture-&gt;set_rotation(adj-&gt;get_value());
...void doSomething(const Cairo::RefPtr&lt;Cairo::Context&gt;&amp; context, int x)
{
    context-&gt;save();
    // change graphics state
    // perform drawing operations
    context-&gt;restore();
}void drag_dest_set(const std::vector&lt;Gtk::TargetEntry&gt;&amp; targets,
    Gtk::DestDefaults flags, Gdk::DragAction actions);void drag_source_set(const std::vector&lt;Gtk::TargetEntry&gt;&amp; targets,
      Gdk::ModifierType start_button_mask, Gdk::DragAction actions);void pack_start(Gtk::Widget&amp; child,
                Gtk::PackOptions options = Gtk::PACK_EXPAND_WIDGET,
                guint padding = 0);where <parameter>condition</parameter> is as specified above. As usual the slot is created with <function>sigc::mem_fun()</function> (for a member method of an object), or <function>sigc::ptr_fun()</function> (for a function).wrap_init_flagsxgettext -a -o my-strings --omit-header *.cc *.hProject-Id-Version: gtkmm-documentation master
POT-Creation-Date: 2013-12-19 14:09+0000
PO-Revision-Date: 2013-12-22 09:03+0300
Last-Translator: Dimitris Spingos (Δημήτρης Σπίγγος) <dmtrs32@gmail.com>
Language-Team: www.gnome.gr
Language: el
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Plural-Forms: nplurals=2; plural=(n != 1);
X-Generator: Virtaal 0.7.1

        GtkSizeRequestMode gtk_widget_get_request_mode(GtkWidget* widget);
      
        GtkToolItem* gtk_tool_button_new(GtkWidget* icon_widget, const gchar*
        label);
      
        _INITIALIZATION(`Gdk::Rectangle&amp;',`GdkRectangle', `$3 =
        Glib::wrap(&amp;($4))')
      
        _INITIALIZATION(`SizeRequestMode&amp;',`GtkSizeRequestMode',`$3 =
        ($1)($4)')
      
        _INITIALIZATION(`SizeRequestMode&amp;',`GtkSizeRequestMode',`$3 =
        (SizeRequestMode)($4)')
      
        _WRAP_CTOR(ToolButton(Widget&amp; icon_widget, const Glib::ustring&amp;
        label{?}), gtk_tool_button_new)
      
        _WRAP_METHOD(bool get_cell_rect(const TreeModel::Path&amp; path, const
        CellRenderer&amp; cell, Gdk::Rectangle&amp; rect{&gt;&gt;}) const,
        gtk_icon_view_get_cell_rect)
      
        _WRAP_METHOD(void get_request_mode(SizeRequestMode&amp; mode{OUT})
        const, gtk_widget_get_request_mode)
      
        _WRAP_METHOD(void set_device_events(Gdk::EventMask events{.}, const
        Glib::RefPtr&lt;const Gdk::Device&gt;&amp; device{.}),
        gtk_widget_set_device_events)
      
        _WRAP_METHOD(void set_device_events(Gdk::EventMask events{events},
        const Glib::RefPtr&lt;const Gdk::Device&gt;&amp; device{device}),
        gtk_widget_set_device_events)
      
        gboolean gtk_icon_view_get_cell_rect(GtkIconView* icon_view,
        GtkTreePath* path, GtkCellRenderer* cell, GdkRectangle* rect);
      
        void gtk_widget_set_device_events(GtkWidget* widget, GdkDevice* device,
        GdkEventMask events);
      
    ...
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
    ...

  $ git clone git://git.gnome.org/mm-common
  $ cp -a mm-common/skeletonmm libsomethingmm

# ./configure
# make
# make install

#include &lt;gtkmm/bin.h&gt;
#include &lt;gtkmm/activatable.h&gt;
_DEFS(gtkmm,gtk)
_PINCLUDE(gtkmm/private/bin_p.h)

namespace Gtk
{

class Button
  : public Bin,
    public Activatable
{
  _CLASS_GTKOBJECT(Button,GtkButton,GTK_BUTTON,Gtk::Bin,GtkBin)
  _IMPLEMENTS_INTERFACE(Activatable)
public:

  _CTOR_DEFAULT
  explicit Button(const Glib::ustring&amp; label, bool mnemonic = false);

  _WRAP_METHOD(void set_label(const Glib::ustring&amp; label), gtk_button_set_label)

  ...

  _WRAP_SIGNAL(void clicked(), "clicked")

  ...

  _WRAP_PROPERTY("label", Glib::ustring)
};

} // namespace Gtk

#include &lt;gtkmm/button.h&gt;

class OverriddenButton : public Gtk::Button
{
protected:
    virtual void on_clicked();
}

void OverriddenButton::on_clicked()
{
    std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;

    // κλήση της έκδοσης της μεθόδου της κλάσης βάσης:
    Gtk::Button::on_clicked();
}

#include &lt;gtkmm/button.h&gt;

void on_button_clicked()
{
    std::cout &lt;&lt; "Hello World" &lt;&lt; std::endl;
}

main()
{
    Gtk::Button button("Hello World");
    button.signal_clicked().connect(sigc::ptr_fun(&amp;on_button_clicked));
}

#include &lt;gtkmm/button.h&gt;
#include &lt;gtkmm/window.h&gt;
class Foo : public Gtk::Window
{
private:
  Gtk::Button theButton;
  // θα καταστραφεί όταν το αντικείμενο Foo καταστραφεί
};

#include &lt;libsomething.h&gt;

int main(int, char**)
{
  something_init();

  std::cout &lt;&lt; get_defs(SOME_TYPE_WIDGET)
            &lt;&lt; get_defs(SOME_TYPE_STUFF);
  return 0;
}

$ ./enum.pl /usr/include/gtk-3.0/gtk/*.h &gt; gtk_enums.defs

$ ./h2def.py /usr/include/gtk-3.0/gtk/*.h &gt; gtk_methods.defs

$ cd gtk/src
$ /usr/lib/glibmm-2.4/proc/gmmproc -I ../../tools/m4 --defs . button . ./../gtkmm

$ cd tools/extra_defs_gen
$ ./generate_extra_defs &gt; gtk_signals.defs

$ for f in $(find libsomethingmm -depth -name '*skeleton*'); do \
    d="${f%/*}"; b="${f##*/}"; mv "$f" "$d/${b//skeleton/libsomething}"; \
  done

&gt; gdb with_signal
(gdb) catch throw
Catchpoint 1 (throw)
(gdb) run
Catchpoint 1 (exception thrown), 0x00714ff0 in __cxa_throw ()
(gdb) backtrace
#0  0x00714ff0 in __cxa_throw () from /usr/lib/i386-linux-gnu/libstdc++.so.6
#1  0x08048bd4 in throwSomething () at with_signal.cc:6
(gdb) continue
Continuing.
(with_signal:2375): glibmm-ERROR **
unhandled exception (type unknown) in signal handler

Program received signal SIGTRAP, Trace/breakpoint trap.

&gt; gdb with_signal
(gdb) run
(with_signal:2703): glibmm-ERROR **:
unhandled exception (type unknown) in signal handler

Program received signal SIGTRAP, Trace/breakpoint trap.
(gdb) backtrace
#2  0x0063c6ab in glibmm_unexpected_exception () at exceptionhandler.cc:77
#3  Glib::exception_handlers_invoke () at exceptionhandler.cc:150
#4  0x0063d370 in glibmm_source_callback (data=0x804d620) at main.cc:212
#13 0x002e1b31 in Gtk::Application::run (this=0x804f300) at application.cc:178
#14 0x08048ccc in main (argc=1, argv=0xbfffecd4) at with_signal.cc:16

&gt; gdb without_signal
(gdb) run
terminate called after throwing an instance of 'char const*'

Program received signal SIGABRT, Aborted.
(gdb) backtrace
#7  0x08048864 in throwSomething () at without_signal.cc:6
#8  0x0804887d in main (argc=1, argv=0xbfffecd4) at without_signal.cc:12

(gdb) catch throw
(gdb) commands
(gdb)   backtrace
(gdb)   continue
(gdb)   end
(gdb) set pagination off
(gdb) run

// _MEMBER_GET_PTR(engine_lang, lang_engine, EngineLang*, PangoEngineLang*)
// Είναι απλά ένα σχόλιο. Είναι δύσκολο να βρεθεί ένα πραγματικό παράδειγμα.

// σε μια κλάση που κληρονομεί από Gtk::Window...
Glib::RefPtr&lt;PrintOperation&gt; op = PrintOperation::create();
// ...ρύθμιση λειτουργίας...
op-&gt;run(Gtk::PRINT_OPERATION_ACTION_PREVIEW, *this);

// Στην μέθοδο της κλάσης ExampleWindow...
Glib::RefPtr&lt;PrintOperation&gt; op = PrintOperation::create();
// ...Ορίστε τη λειτουργία...
op-&gt;signal_done().connect(sigc::bind(sigc::mem_fun(*this, &amp;ExampleWindow::on_printoperation_done), op));
// Εκτελέστε τη λειτουργία

// with_signal.cc
#include &lt;gtkmm.h&gt;

bool throwSomething()
{
  throw "Something";
  return true;
}

int main(int argc, char** argv)
{
  Glib::signal_timeout().connect(sigc::ptr_fun(throwSomething), 500);
  Glib::RefPtr&lt;Gtk::Application&gt; app =
    Gtk::Application::create(argc, argv, "org.gtkmm.with_signal");
  app-&gt;hold();
  return app-&gt;run();
}

// without_signal.cc
#include &lt;gtkmm.h&gt;

bool throwSomething()
{
  throw "Something";
  return true;
}

int main(int argc, char** argv)
{
  throwSomething();
  Glib::RefPtr&lt;Gtk::Application&gt; app =
    Gtk::Application::create(argc, argv, "org.gtkmm.without_signal");
  return app-&gt;run();
}

//Μέσα σε μια κλάση που κληρονομεί από Gtk::Window και διατηρεί m_refPageSetup και m_refSettings ως μέλη...
Glib::RefPtr&lt;Gtk::PageSetup&gt; new_page_setup = Gtk::run_page_setup_dialog(*this, m_refPageSetup, m_refSettings);
m_refPageSetup = new_page_setup;

Button::Button(const Glib::ustring&amp; label, bool mnemonic)
:
  _CONSTRUCT("label", label.c_str(), "use_underline", gboolean(mnemonic))
{}

DerivedDialog* pDialog = 0;
builder-&gt;get_widget_derived("DialogBasic", pDialog);

DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr&lt;Gtk::Builder&gt;&amp; builder)
: Gtk::Dialog(cobject)
{
}

DerivedDialog::DerivedDialog(BaseObjectType* cobject, const Glib::RefPtr&lt;Gtk::Builder&gt;&amp; builder)
: Gtk::Dialog(cobject),
  m_builder(builder),
  m_pButton(0)
{
  //Λήψη του στιγμιοτύπου κουμπιού Glade και σύνδεση με χειριστή σήματος:
  m_builder-&gt;get_widget("quit_button", m_pButton);
  if(m_pButton)
  {
    m_pButton-&gt;signal_clicked().connect( sigc::mem_fun(*this, &amp;DerivedDialog::on_button_quit) );
  }
}

Glib::RefPtr&lt;Gdk::Pixbuf&gt; pixbuf = Gdk::Pixbuf::create_from_file(filename);

Glib::RefPtr&lt;Gdk::Pixbuf&gt; pixbuf2 = pixbuf;

Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
Gdk::Pixbuf&amp; underlying = *refPixbuf; //Σφάλμα σύνταξης - δεν θα μεταγλωττίσει.

Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf2 = refPixbuf;

Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
int width = refPixbuf-&gt;get_width();

Glib::RefPtr&lt;Gtk::Builder&gt; builder = Gtk::Builder::create_from_file("basic.glade");

Glib::RefPtr&lt;Gtk::Builder&gt; builder = Gtk::Builder::create_from_file("basic.glade", "treeview_products");

Glib::RefPtr&lt;Gtk::PrintOperation&gt; op = Gtk::PrintOperation::create();
// ...Ρύθμιση λειτουργίας...
op-&gt;set_export_filename("test.pdf");
Gtk::PrintOperationResult res = op-&gt;run(Gtk::PRINT_OPERATION_ACTION_EXPORT);

Glib::RefPtr&lt;Gtk::TreeModel&gt; refModel = m_TreeView.get_model();
if(refModel)
{
  int cols_count = refModel-&gt;get_n_columns();
  ...
}

Glib::RefPtr&lt;Gtk::TreeStore&gt; refStore =
Glib::RefPtr&lt;Gtk::TreeStore&gt;::cast_dynamic(refModel);
Glib::RefPtr&lt;Gtk::TreeStore&gt; refStore2 =
Glib::RefPtr&lt;Gtk::TreeStore&gt;::cast_static(refModel);

Glib::RefPtr&lt;Gtk::TreeStore&gt; refStore = Gtk::TreeStore::create(columns);
Glib::RefPtr&lt;Gtk::TreeModel&gt; refModel = refStore;

Glib::SignalProxy1&lt;bool, Gtk::DirectionType&gt; signal_focus()

Glib::SignalProxy3&lt;void, const TextBuffer::iterator&amp;, const Glib::ustrin&amp;, int&gt; signal_insert();

Gtk::Button* button = new Gtk::Button("example");
gtk_button_do_something_new(button-&gt;gobj());

Gtk::Button* pButton = new Gtk::Button("Test");

// κάντε κάτι χρήσιμο με το pButton

delete pButton;

Gtk::Dialog* pDialog = 0;
builder-&gt;get_widget("DialogBasic", pDialog);

Gtk::ToolButton* button = Gtk::manage(new Gtk::ToolButton(icon, "Big"));
button-&gt;set_tooltip_text("Big Brush);
group_brushes-&gt;insert(*button);

Gtk::ToolItemGroup* group_brushes =
  Gtk::manage(new Gtk::ToolItemGroup("Brushes"));
m_ToolPalette.add(*group_brushes);

Gtk::Widget* CustomPrintOperation::on_create_custom_widget()
{
  set_custom_tab_label("My custom tab");

  Gtk::Box* hbox = new Gtk::Box(Gtk::ORIENTATION_HORIZONTAL, 8);
  hbox-&gt;set_border_width(6);

  Gtk::Label* label = Gtk::manage(new Gtk::Label("Enter some text: "));
  hbox-&gt;pack_start(*label, false, false);
  label-&gt;show();

  hbox-&gt;pack_start(m_Entry, false, false);
  m_Entry.show();

  return hbox;
}

void CustomPrintOperation::on_custom_widget_apply(Gtk::Widget* /* widget */)
{
  Glib::ustring user_input = m_Entry.get_text();
  //...
}

GtkButton* cbutton = get_a_button();
Gtk::Button* button = Glib::wrap(cbutton);

GtkWidget* example_widget_new(int something, const char* thing)
{
        ExampleWidget* widget;
        widget = g_object_new (EXAMPLE_TYPE_WIDGET, NULL);
        example_widget_construct(widget, "something", something, "thing", thing);
}

void example_widget_construct(ExampleWidget* widget, int something, const char* thing)
{
        //Do stuff that uses private API:
        widget-&gt;priv-&gt;thing = thing;
        do_something(something);
}

GtkWidget* example_widget_new(int something, const char* thing)
{
        return g_object_new (EXAMPLE_TYPE_WIDGET, "something", something, "thing", thing, NULL);
}

MyContainer::MyContainer()
{
  Gtk::Button* pButton = Gtk::manage(new Gtk::Button("Test"));
  add(*pButton); //προσθήκη του *pButton στο MyContainer
}

_CLASS_BOXEDTYPE(RGBA, GdkRGBA, NONE, gdk_rgba_copy, gdk_rgba_free)

_CLASS_BOXEDTYPE_STATIC(Rectangle, GdkRectangle)

_CLASS_GENERIC(AttrIter, PangoAttrIterator)

_CLASS_GOBJECT(AccelGroup, GtkAccelGroup, GTK_ACCEL_GROUP, Glib::Object, GObject)

_CLASS_GTKOBJECT(Button, GtkButton, GTK_BUTTON, Gtk::Bin, GtkBin)

_CLASS_INTERFACE(CellEditable, GtkCellEditable, GTK_CELL_EDITABLE, GtkCellEditableIface)

_CLASS_INTERFACE(LoadableIcon, GLoadableIcon, G_LOADABLE_ICON, GLoadableIconIface, Icon, GIcon)

_CLASS_OPAQUE_COPYABLE(Checksum, GChecksum, NONE, g_checksum_copy, g_checksum_free)

_CLASS_OPAQUE_REFCOUNTED(Coverage, PangoCoverage, pango_coverage_new, pango_coverage_ref, pango_coverage_unref)

_CONVERSION(`GtkTreeView*',`TreeView*',`Glib::wrap($3)')

_CONVERSION(`PrintSettings&amp;',`GtkPrintSettings*',__FR2P)
_CONVERSION(`const PrintSettings&amp;',`GtkPrintSettings*',__FCR2P)
_CONVERSION(`const Glib::RefPtr&lt;Printer&gt;&amp;',`GtkPrinter*',__CONVERT_REFPTR_TO_P($3))

_IGNORE(gtk_button_box_set_spacing, gtk_button_box_get_spacing)

_IMPLEMENTS_INTERFACE(Activatable)

_INITIALIZATION(`Gtk::Widget&amp;',`GtkWidget*',`$3 = Glib::wrap($4)')

_MEMBER_GET_GOBJECT(layout, layout, Pango::Layout, PangoLayout*)

_WRAP_ENUM(IconLookupFlags, GtkIconLookupFlags, NO_GTYPE)

_WRAP_ENUM(WindowType, GtkWindowType)

_WRAP_GERROR(PixbufError, GdkPixbufError, GDK_PIXBUF_ERROR)

_WRAP_METHOD(void set_text(const Glib::ustring&amp; text), gtk_entry_set_text)

_WRAP_METHOD_DOCS_ONLY(gtk_container_remove)

_WRAP_PROPERTY("label", Glib::ustring)

_WRAP_SIGNAL(void clicked(),"clicked")

_WRAP_VFUNC(SizeRequestMode get_request_mode() const, get_request_mode)

bool MyCallback() { std::cout &lt;&lt; "Hello World!\n" &lt;&lt; std::endl; return true; }

bool idleFunc();

bool input_callback(Glib::IOCondition condition);

bool on_button_press(GdkEventButton* event);
Gtk::Button button("label");
button.signal_button_press_event().connect( sigc::ptr_fun(&amp;on_button_press) );

bool on_key_press_or_release_event(GdkEventKey* event)
{
  if (event-&gt;type == GDK_KEY_PRESS &amp;&amp;
    event-&gt;keyval == GDK_KEY_1 &amp;&amp;
    (event-&gt;state &amp; (GDK_SHIFT_MASK | GDK_CONTROL_MASK | GDK_MOD1_MASK)) == GDK_MOD1_MASK)
  {
    handle_alt_1_press(); // GDK_MOD1_MASK is normally the Alt key
    return true;
  }
  return false;
}

Gtk::Entry m_entry; // στον ορισμό κλάσης

// στον κατασκευαστή κλάσης
m_entry.signal_key_press_event().connect( sigc::ptr_fun(&amp;on_key_press_or_release_event) );
m_entry.signal_key_release_event().connect( sigc::ptr_fun(&amp;on_key_press_or_release_event) );
m_entry.add_events(Gdk::KEY_PRESS_MASK | Gdk::KEY_RELEASE_MASK);

button.signal_button_press_event().connect( sigc::ptr_fun(&amp;on_mywindow_button_press), false );

class Server
{
public:
  //στοιχείο πρόσβασης σήματος:
  typedef sigc::signal&lt;void, bool, int&gt; type_signal_something;
  type_signal_something signal_something();

protected:
  type_signal_something m_signal_something;
};

Server::type_signal_something Server::signal_something()
{
  return m_signal_something;
}

class TextMark : public Glib::Object
{
  _CLASS_GOBJECT(TextMark, GtkTextMark, GTK_TEXT_MARK, Glib::Object, GObject)

protected:
  _WRAP_CTOR(TextMark(const Glib::ustring&amp; name, bool left_gravity = true), gtk_text_mark_new)

public:
  _WRAP_CREATE(const Glib::ustring&amp; name, bool left_gravity = true)

example-widget.h:56: error: using typedef-name 'ExampleWidget' after 'struct'
../../libexample/libexamplemm/example-widget.h:34: error: 'ExampleWidget' has a previous declaration here
make[4]: *** [example-widget.lo] Error 1

example-widget.h:60: error: '_ExampleWidget ExampleWidget' redeclared as different kind of symbol
../../libexample/libexamplemm/example-widget.h:34: error: previous declaration of 'typedef struct _ExampleWidget ExampleWidget'

int width = 0;
if(pixbuf)
{
  width = pixbuf-&gt;get_width();
}

m_button1.signal_clicked().connect( sigc::bind&lt;Glib::ustring&gt;( sigc::mem_fun(*this, &amp;HelloWorld::on_button_clicked), "button 1") );

my_connection.disconnect();

server.signal_something().connect(
  sigc::mem_fun(client, &amp;Client::on_server_something) );

sigc::connection  Glib::SignalIdle::connect(const sigc::slot&lt;bool&gt;&amp; slot,
                                    int priority = Glib::PRIORITY_DEFAULT_IDLE);

sigc::connection Glib::SignalIO::connect(const sigc::slot&lt;bool,Glib::IOCondition&gt;&amp; slot,
                                 int fd, Glib::IOCondition condition,
                                 int priority = Glib::PRIORITY_DEFAULT);

sigc::connection Glib::SignalTimeout::connect(const sigc::slot&lt;bool&gt;&amp; slot,
                                      unsigned int interval, int priority = Glib::PRIORITY_DEFAULT);

sigc::signal&lt;void, bool, int&gt; signal_something;

sigc::signal&lt;void,int&gt;::iterator signal&lt;void,int&gt;::connect( const sigc::slot&lt;void,int&gt;&amp; );

std::list&lt; Glib::RefPtr&lt;Gdk::Pixbuf&gt; &gt; listPixbufs;
Glib::RefPtr&lt;Gdk::Pixbuf&gt; refPixbuf = Gdk::Pixbuf::create_from_file(filename);
listPixbufs.push_back(refPixbuf);

typedef struct _ExampleWidget ExampleWidget;

struct _ExampleWidget
{
  ...
};

virtual void on_button_clicked(Glib::ustring data);

void ExampleWindow::on_printoperation_done(Gtk::PrintOperationResult result, const Glib::RefPtr&lt;PrintOperation&gt;&amp; op)
{
  if (result == Gtk::PRINT_OPERATION_RESULT_ERROR)
    //ειδοποιήστε τον χρήστη
  else if (result == Gtk::PRINT_OPERATION_RESULT_APPLY)
    //Ενημερώστε τις ρυθμίσεις εκτύπωσης με αυτές που χρησιμοποιούνται στον προσανατολισμό εκτύπωσης

  if (! op-&gt;is_finished())
    op-&gt;signal_status_changed().connect(sigc::bind(sigc::mem_fun(*this, &amp;ExampleWindow::on_printoperation_status_changed), op));
}

void ExampleWindow::on_printoperation_status_changed(const Glib::RefPtr&lt;PrintFormOperation&gt;&amp; op)
{
  if (op-&gt;is_finished())
    //Η εργασία εκτύπωσης τελείωσε
  else
    //πάρτε την κατάσταση με get_status() ή get_status_string()

  //Ενημέρωση της διεπαφής χρήστη
}

void init()
{
  Gtk::Main::init_gtkmm_internals(); //Sets up the g type system and the Glib::wrap() table.
  wrap_init(); //Tells the Glib::wrap() table about the libsomethingmm classes.
}

void on_button_clicked();

class some_class
{
    void on_button_clicked();
};

some_class some_object;

main()
{
    Gtk::Button button;
    button.signal_clicked().connect( sigc::ptr_fun(&amp;on_button_clicked) );
    button.signal_clicked().connect( sigc::mem_fun(some_object, &amp;some_class::on_button_clicked) );
}

void on_insert(const TextBuffer::iterator&amp; pos, const Glib::ustring&amp; text, int bytes)

{
  Gtk::Button aButton;
  aButton.show();
  ...
  app-&gt;run();
}
"Κρυφές" στήλες# keep this file sorted alphabetically, one language code per line
de
ja#include &lt;gtkmm.h&gt;#m4 _CONVERSION(`GSList*',`std::vector&lt;Widget*&gt;',`Glib::SListHandler&lt;Widget*&gt;::slist_to_vector($3, Glib::OWNERSHIP_SHALLOW)')$ ./plug &amp;$ ./socket(Μια παρένθεση: η <application>GTK+</application> αποκαλεί αυτό το σχήμα "σηματοδότηση"· ο ανοιχτομάτης αναγνώστης με εμπειρία πακέτου εργαλείων GUI θα σημειώσει ότι αυτή η ίδια σχεδίαση εμφανίζεται συχνά κάτω από το όνομα "εκφώνηση-ακρόαση" (π.χ. στο σκελετό PowerPlant του Metrowerks για το Macintosh). Δουλεύει χοντρικά με τον ίδιο τρόπο: ένας ρυθμίζει την <literal>εκφώνηση</literal> και έπειτα συνδέει την <literal>ακρόαση</literal> με αυτήν· η εκφώνηση κρατά έναν κατάλογο των αντικειμένων που την ακούν και όταν κάποιος δώσει ένα μήνυμα στην εκφώνηση, καλεί όλα τα αντικείμενά της στον κατάλογό της με το μήνυμα. Στην <application>gtkmm</application>, τα αντικείμενα σήματος παίζουν τον ρόλο της εκφώνησης και οι υποδοχές παίζουν τον ρόλο της ακρόασης - κατά κάποιον τρόπο. Περισσότερο για αυτό αργότερα.)(Επιπλέον, θα έχετε τα αρχεία <literal>ja.po</literal> και <literal>de.po</literal> στον κατάλογό σας <literal>po</literal> που περιέχει την γερμανική και ιαπωνική μετάφραση, αντίστοιχα.)./docextract_to_xml.py -s ~/checkout/gnome/gtk+/gtk/ &gt; gtk_docs.xml
// δημιουργεί τις δικές του προσαρμογές
Gtk::TextView textview·
// χρησιμοποιεί την νεοδημιουργούμενη προσαρμογή για τη γραμμή κύλισης επίσης
Gtk::Scrollbar vscrollbar (textview.get_vadjustment(), Gtk::ORIENTATION_VERTICAL)·// σημείωση στους μεταφραστές: μην μεταφράζετε το τμήμα "[noun]" είναι
// εδώ απλά για να ξεχωρίσει τη συμβολοσειρά από μια άλλη συμβολοσειρά "jumps"
text = strip(gettext("jumps[noun]"), "[noun]");//compiler error - no conversion from ustring to int.
int number = row[m_Columns.m_col_text];2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010Η <application>Gtk::Builder</application> ελέγχει για έναν μηδενικό δείκτη και ελέγχει ότι το γραφικό συστατικό είναι του αναμενόμενου τύπου και θα εμφανίσει προειδοποιήσεις στη γραμμή εντολών για αυτά.Η <application>glibmm</application> παρέχει το κανονικό σύνολο των συναρτήσεων εκκίνησης νήματος, αμοιβαίων αποκλεισμών, μεταβλητών συνθηκών και κλάσεων κλειδώματος εμβέλειας που απαιτούνται για συγγραφή πολυνηματικών προγραμμάτων χρησιμοποιώντας την C++.Η <application>gtkmm</application> 3 πρόσθεσε μερικές νέες κλάσεις:Η <application>gtkmm</application> 3 επίσης έκανε πολλές μικρές αλλαγές στην API, τις οποίες προφανώς θα αντιμετωπίσετε κατά τη μεταφορά κώδικα που χρησιμοποιήθηκε στο <application>gtkmm</application>-2.4. Να μια σύντομη λίστα:Η βιβλιοθήκη της <application>gtkmm</application> 3 λέγεται <literal>libgtkmm-3.0</literal> αντί για <literal>libgtkmm-2.4</literal> και εγκαθιστά τις κεφαλίδες της σε έναν κατάλογο παρόμοιας έκδοσης, έτσι ο έλεγχος σας pkg-config πρέπει να ζητήσει για <literal>gtkmm-3.0</literal> αντί για <literal>gtkmm-2.4</literal>.Η <application>gtkmm</application> επιτρέπει στον προγραμματιστή να ελέγξει τον χρόνο ζωής (δηλαδή, την κατασκευή και καταστροφή) οποιουδήποτε γραφικού συστατικού με τον ίδιο τρόπο όπως οποιοδήποτε άλλο αντικείμενο C++. Αυτή η ευελιξία επιτρέπει τη χρήση των <literal>new</literal> και <literal>delete</literal> για τη δημιουργία και καταστροφή αντικειμένων δυναμικά ή τη χρήση κανονικών μελών κλάσης (που καταστρέφονται αυτόματα όταν καταστρέφεται η κλάση) ή τη χρήση τοπικών στιγμιοτύπων (που καταστρέφονται όταν το στιγμιότυπο βγαίνει εκτός εμβέλειας). Αυτή η ευελιξία δεν παρουσιάζεται σε μερικά πακέτα εργαλείων GUI της C++, που περιορίζει τον προγραμματιστή σε ένα υποσύνολο μόνο των γνωρισμάτων διαχείρισης μνήμης της C++.Η <application>gtkmm</application> επιτρέπει τη συγγραφή κώδικα χρησιμοποιώντας κανονικές τεχνικές C++ όπως ενθυλάκωση, παραγωγή και πολυμορφισμό. Ως προγραμματιστής C++ θα καταλάβατε ήδη ότι αυτό οδηγεί σε σαφέστερο και καλύτερα οργανωμένο κώδικα.Η <application>gtkmm</application> και η Win32Οι εφαρμογές <application>gtkmm</application> μπορούν εύκολα να υποστηρίξουν πολλαπλές γλώσσες, συμπεριλαμβανομένων μη ευρωπαϊκών γλωσσών όπως κινέζικα και γλώσσες από δεξιά προς τα αριστερά όπως αραβικά. Μια κατάλληλα γραμμένη και μεταφρασμένη εφαρμογή <application>gtkmm</application> θα χρησιμοποιήσει την κατάλληλη γλώσσα στον χρόνο εκτέλεσης με βάση το περιβάλλον του χρήστη.Οι εφαρμογές της <application>gtkmm</application> αποτελούνται από παράθυρα που περιέχουν γραφικά συστατικά, όπως κουμπιά και πλαίσια κειμένου. Σε μερικά άλλα συστήματα, τα γραφικά συστατικά λέγονται "στοιχεία ελέγχου". Για κάθε γραφικό συστατικό στα παράθυρα της εφαρμογής σας, υπάρχει ένα αντικείμενο C++ στον κώδικα της εφαρμογής σας. Έτσι χρειάζεστε απλά να καλέσετε μια μέθοδο της κλάσης του γραφικού συστατικού για να επηρεάσετε το ορατό γραφικό συστατικό.Το <application>gtkmm</application> τακτοποιεί τα γραφικά συστατικά ιεραρχικά, χρησιμοποιώντας <emphasis>περιέκτες</emphasis>. Ένα γραφικό συστατικό περιέκτη περιέχει άλλα γραφικά συστατικά. Τα περισσότερα γραφικά συστατικά του <application>gtkmm</application> είναι περιέκτες. Παράθυρα, καρτέλες σημειωματάριου και κουμπιά είναι όλα γραφικά συστατικά περιεκτών. Υπάρχουν δύο γεύσεις περιεκτών: περιέκτες μοναδικού θυγατρικού, που είναι όλοι απόγονοι της <classname>Gtk::Bin</classname>, και περιέκτες πολλαπλών θυγατρικών, που είναι απόγονοι της <classname>Gtk::Container</classname>. Τα περισσότερα γραφικά συστατικά στο <application>gtkmm</application> είναι απόγονοι της <classname>Gtk::Bin</classname>, συμπεριλαμβανόμενης της <classname>Gtk::Window</classname>.Οι κλάσεις <application>gtkmm</application> σχεδιάζονται με την αντικατάσταση κατά νου· περιέχουν εικονικές μεθόδους μέλους με ειδικό σκοπό να αντικατασταθούν.Η <application>gtkmm</application> συγκρινόμενη με τη QtΗ <application>gtkmm</application> προς το παρόν δουλεύει με τον <ulink url="http://mingw.org/">MingW/μεταγλωττιστή GCC3.4</ulink> και την Microsoft Visual C++ 2005 ή μεταγενέστερες (συμπεριλαμβάνοντας τις ελεύθερα διαθέσιμες γρήγορες εκδόσεις) σε λειτουργικό Windows. Υπάρχει ένας <ulink url="ftp://ftp.gnome.org/pub/GNOME/binaries/win32/gtkmm">εγκαταστάτης</ulink> διαθέσιμος για gtkmm στην Microsoft Windows. Δείτε την <ulink url="http://live.gnome.org/gtkmm/MSWindows/">http://live.gnome.org/gtkmm/MSWindows</ulink> για οδηγίες χρήσης.Οι προγραμματιστές της <application>gtkmm</application> τείνουν να προτιμούν τη <application>gtkmm</application> από τη Qt επειδή η <application>gtkmm</application> κάνει πράγματα με έναν πιο C++ τρόπο. Η Qt προέρχεται από μια εποχή όταν η C++ και η τυπική βιβλιοθήκη δεν είχαν προτυποποιηθεί ή δεν υποστηριζόντουσαν καλά από μεταγλωττιστές. Συνεπώς, διπλοεγγράφει πολύ υλικό που είναι τώρα στην τυπική βιβλιοθήκη, όπως περιέκτες και πληροφορίες τύπων. Πιο σημαντικό, η Trolltech τροποποίησε τη γλώσσα C++ για να δώσει σήματα, έτσι ώστε οι κλάσεις Qt δεν μπορούν να χρησιμοποιηθούν εύκολα με μη Qt κλάσεις. Η <application>gtkmm</application> μπορούσε να χρησιμοποιήσει την τυπική C++ για να παράσχει σήματα χωρίς αλλαγή της γλώσσας C++. Δείτε το <ulink url="https://wiki.gnome.org/gtkmm/FAQ">συχνές ερωτήσεις</ulink> για περισσότερο λεπτομερείς διαφορές.Η <application>gtkmm</application> έχει ποικίλα γραφικά συστατικά που μπορούν να προσαρμοστούν οπτικά χρησιμοποιώντας το ποντίκι ή το πληκτρολόγιο, όπως τα γραφικά συστατικά <classname>Range</classname> (που περιγράφηκαν στην ενότητα <link linkend="chapter-range-widgets">Γραφικά συστατικά περιοχής</link>). Υπάρχουν επίσης λίγα γραφικά συστατικά που εμφανίζουν κάποιο ρυθμίσιμο μέρος μιας μεγαλύτερης περιοχής, όπως το γραφικό συστατικό <classname>Viewport</classname>. Αυτά τα γραφικά συστατικά έχουν αντικείμενα <classname>Gtk::Adjustment</classname> που εκφράζουν αυτό το κοινό τμήμα της API τους.Η <application>gtkmm</application> εμπεριέχει λιγότερο κώδικα συγκρινόμενη με τη GTK+, που χρησιμοποιεί ονόματα συναρτήσεων με πρόθεμα και πολλές αποχρώσεις μακροεντολών.Η <application>gtkmm</application> είναι ένας συσκευαστής C++ για το <ulink url="http://www.gtk.org/">GTK+</ulink>, μια βιβλιοθήκη που χρησιμοποιείται για τη δημιουργία γραφικών διεπαφών χρήστη. Αδειοδοτείται χρησιμοποιώντας την άδεια LGPL, έτσι μπορείτε να αναπτύξετε ανοικτό λογισμικό, ελεύθερο λογισμικό, ή ακόμα εμπορικό μη ελεύθερο λογισμικό χρησιμοποιώντας τη <application>gtkmm</application> χωρίς την αγορά αδειών.Η <application>gtkmm</application> είναι ένας συσκευαστήςΗ <application>gtkmm</application> είναι περισσότερο ασφαλές στους τύπους, έτσι ο μεταγλωττιστής μπορεί να αναγνωρίσει σφάλματα που θα μπορούσαν να ανιχνευτούν μόνο κατά τον χρόνο εκτέλεσης, κατά τη χρήση της C. Αυτή η χρήση ειδικών τύπων κάνει επίσης το API σαφέστερο, επειδή μπορείτε να δείτε τι τύποι πρέπει να χρησιμοποιηθούν κοιτώντας απλά σε μια δήλωση μεθόδου.Η <application>gtkmm</application> δεν είναι ένα εγγενές πακέτο εργαλείων C++, αλλά ένας συσκευαστής ενός πακέτου εργαλείων C. Αυτή ο χωρισμός της διεπαφής και της υλοποίησης έχει πλεονεκτήματα. Οι προγραμματιστές της <application>gtkmm</application> διαθέτουν τον περισσότερο χρόνο τους συζητώντας πώς η <application>gtkmm</application> μπορεί να παρουσιάσει τη πιο σαφή API, χωρίς περίεργους συμβιβασμούς λόγω των ασαφών τεχνικών λεπτομερειών. Συνεισφέρουμε λίγο στον υποκείμενο κώδικα βάσης GTK+, αλλά το ίδιο κάνουν και οι κωδικογράφοι της C και της Perl και του Python, κλπ. Συνεπώς η GTK+ επωφελείται από μια πλατύτερη βάση χρήστη από τα ειδικά πακέτα εργαλείων γλώσσας - υπάρχουν περισσότερα άτομα για υλοποίηση, ανάπτυξη, έλεγχο και χρήση.Η <application>gtkmm</application> διευκολύνει την παραγωγή νέων γραφικών συστατικών κληρονομώντας από μια υπάρχουσα κλάση γραφικών συστατικών, είτε παράγοντας από έναν περιέκτη και προσθέτοντας θυγατρικά γραφικά συστατικά, ή παράγοντας από ένα γραφικό συστατικό μοναδικού στοιχείου και αλλάζοντας τη συμπεριφορά του. Αλλά μπορεί να βρείτε ενίοτε ότι δεν υπάρχει κατάλληλο αρχικό σημείο ήδη. Σε αυτήν την περίπτωση, μπορείτε να υλοποιήσετε ένα γραφικό συστατικό από την αρχή.Η <application>gtkmm</application> δίνει έναν εύκολο τρόπο διαχείρισης πρόσφατα χρησιμοποιημένων εγγράφων. Οι εμπλεκόμενες κλάσεις στην υλοποίηση αυτής της λειτουργίας είναι <classname>RecentManager</classname>, <classname>RecentChooserDialog</classname>, <classname>RecentChooserMenu</classname>, <classname>RecentChooserWidget</classname>, <classname>RecentAction</classname> και <classname>RecentFilter</classname>.Η <application>gtkmm</application> παρέχει τέσσερις βασικούς τύπους κουμπιών:Η <application>gtkmm</application> παρέχει τη συνάρτηση <function>manage()</function> και τις μεθόδους <methodname>add()</methodname> για δημιουργία και καταστροφή γραφικών συστατικών. Κάθε γραφικό συστατικό εκτός από το παράθυρο ανωτάτου επιπέδου πρέπει να προστεθεί ή να συσκευαστεί σε έναν περιέκτη για να εμφανιστεί. Η συνάρτηση <function>manage()</function> σημειώνει ένα γραφικό συστατικό έτσι ώστε όταν το γραφικό συστατικό προστίθεται σε έναν περιέκτη, ο περιέκτης γίνεται υπεύθυνος για διαγραφή του γραφικού συστατικού.Οι χειριστές σήματος <application>gtkmm</application> είναι ισχυρού τύπου, ενώ ο κώδικας C της <application>GTK+</application> επιτρέπει τη σύνδεση μιας επανάκλησης με τον εσφαλμένο αριθμό και τύπο ορισμάτων, οδηγώντας σε ένα σφάλμα κατάτμησης στον χρόνο εκτέλεσης. Και, αντίθετα με την <application>Qt</application>, η <application>gtkmm</application> το πετυχαίνει χωρίς τροποποίηση της γλώσσας C++.Η <application>gtkmm</application> χρησιμοποιεί το εργαλείο <command>gmmproc</command> για τη δημιουργία του περισσότερου πηγαίου κώδικά της, χρησιμοποιώντας αρχεία .defs που ορίζουν τις APIs των βιβλιοθηκών με βάση την <classname>GObject</classname>. Έτσι είναι αρκετά εύκολη η δημιουργία πρόσθετων συσκευαστών τεχνοτροπίας gtkmm ή άλλων βιβλιοθηκών με βάση glib/GObject.Η <application>gtkmm</application> χρησιμοποιεί τη βιβλιοθήκη libsigc++ για την υλοποίηση σημάτων. Να ένα παράδειγμα γραμμής κώδικα που συνδέει ένα "πατημένο" σήμα του Gtk::Button με έναν χειριστή σήματος που λέγεται "on_button_clicked": <placeholder-1/>Το <application>gtkmm</application> χρησιμοποιεί το σύστημα συσκευασίας για την επίλυση αυτών των προβλημάτων. Αντί να ορίζει τη θέση και το μέγεθος κάθε γραφικού συστατικού στο παράθυρο, μπορείτε να τακτοποιήσετε τα γραφικά συστατικά σας σε γραμμές, στήλες και/ή πλέγματα. Το <application>gtkmm</application> μπορεί να προσαρμόσει το παράθυρό σας αυτόματα, με βάση τα μεγέθη των γραφικών συστατικών που περιέχει. Και τα μεγέθη των γραφικών συστατικών καθορίζονται, με τη σειρά τους, από το πόσο κείμενο περιέχουν, ή το ελάχιστο και μέγιστο μέγεθος που ορίζετε, και/ή πώς έχετε ζητήσει να μοιράζεται ο διαθέσιμος χώρος μεταξύ ομάδων γραφικών συστατικών. Μπορείτε να τελειοποιήσετε τη διάταξή σας ορίζοντας απόσταση συμπλήρωσης και κεντράρισμα τιμών για κάθε γραφικό συστατικό σας. Τότε το <application>gtkmm</application> χρησιμοποιεί όλες αυτές τις πληροφορίες για αυξομείωση και ανατοποθέτηση καθενός λογικά και ομαλά, όταν ο χρήστης χειρίζεται το παράθυρο.Η <application>gtkmm</application> ονομάστηκε αρχικά gtk--, επειδή το GTK+ είχε ήδη ένα + στο όνομά του. Όμως, επειδή το -- δεν ευρετηριοποιείται εύκολα από τις μηχανές αναζήτησης, το πακέτο γενικά έγινε <application>gtkmm</application> και εκεί κολλήσαμε.Οι κλάσεις γραφικών συστατικών <application>gtkmm</application> έχουν μεθόδους στοιχείων πρόσβασης σήματος, όπως <methodname>Gtk::Button::signal_clicked()</methodname>, που επιτρέπουν να συνδεθείτε με τον χειριστή σήματός σας. Χάρη στην ευελιξία της <application>libsigc++</application>, την βιβλιοθήκη επανάκλησης που χρησιμοποιείται από την <application>gtkmm</application>, ο χειριστής σήματος μπορεί να είναι σχεδόν κάθε είδος συνάρτησης, αλλά προφανώς θα θέλετε να χρησιμοποιήσετε μια μέθοδο κλάσεων. Μεταξύ των κωδικοποιητών C της <application>GTK+</application>, αυτοί οι χειριστές σήματος ονομάζονται συχνά επανακλήσεις.Η <application>gtkmm</application>, όπως τα περισσότερα πακέτα εργαλείων γραφικής διεπαφής, <emphasis>οδηγείται από τα συμβάντα</emphasis>. Όταν συμβαίνει ένα γεγονός, όπως το πάτημα ενός πλήκτρου του ποντικιού, το κατάλληλο σήμα θα <emphasis>εκπεμφθεί</emphasis> από το γραφικό συστατικό που πατήθηκε. Κάθε γραφικό συστατικό έχει ένα διαφορετικό σύνολο σημάτων που μπορεί να εκπέμψει. Για να κάνετε ένα πάτημα κουμπιού αποτέλεσμα σε μια ενέργεια, ορίζουμε έναν <emphasis>χειριστή σήματος</emphasis> για τη σύλληψη του σήματος "πατημένο" του κουμπιού.Η <application>gtkmm</application>-3.0 είναι μια νέα έκδοση της API της <application>gtkmm</application> που εγκαθίσταται παράλληλα με την παλιότερη API της <application>gtkmm</application>-2.4. Η τελευταία έκδοση της API της <application>gtkmm</application>-2.4 ήταν η <application>gtkmm</application> 2.24. Η <application>gtkmm</application> 3 δεν έχει κύριες θεμελιακές διαφορές με την <application>gtkmm</application> 2, αλλά κάνει πολλές μικρές αλλαγές που δεν ήταν δυνατές κατά τη διατήρηση δυαδικής συμβατότητας. Αν δεν έχετε ποτέ χρησιμοποιήσει την API της <application>gtkmm</application>-2.4, τότε μπορείτε να αγνοήσετε με ασφάλεια αυτό το κεφάλαιο.Το σενάριο <application>intltool</application> / <application>xgettext</application> εξάγει τις συμβολοσειρές και τις βάζει σε ένα αρχείο <filename>mypackage.pot</filename>. Οι μεταφραστές της εφαρμογής σας δημιουργούν τις μεταφράσεις τους αντιγράφοντας πρώτα αυτό το αρχείο <filename>.pot</filename> σε ένα <filename>localename.po</filename>. Η τοπική ρύθμιση αναγνωρίζει μια γλώσσα και μια κωδικοποίηση για αυτήν τη γλώσσα, συμπεριλαμβανόμενων των μορφών ημερομηνίας και αριθμών. Αργότερα, το κείμενο στον πηγαίο κώδικα έχει αλλάξει, το σενάριο <literal>msmerge</literal> χρησιμοποιείται για ενημέρωση των αρχείων <filename>localename.po</filename> από το αναγεννημένο αρχείο <filename>.pot</filename>.<classname>ButtonBox</classname>es βοηθούν να κάνουν τις εφαρμογές σας να εμφανίζονται συνεπείς, επειδή χρησιμοποιούν τυπικές ρυθμίσεις, όπως διάκενο και συσκευασία μεταξύ κουμπιών.Η <classname>Gdk::Drawable</classname> αφαιρέθηκε, με τις μεθόδους της να μετακινούνται στο <classname>Gdk::Window</classname>.Οι <classname>Gdk::Pixmap</classname> και αφαιρέθηκαν <classname>Gdk::Bitmap</classname> υπέρ της <classname>Gdk::Pixbuf</classname>.Η <classname>Gdk::RGBA</classname> αντικαθιστά την <classname>Color</classname>, προσθέτοντας ένα άλφα συστατικό για αδιαφάνεια. Η <classname>Colormap</classname> αφαιρέθηκε, μαζί με τη περίεργη χρήση της για κατανομή χρωμάτων.<classname>Glib::ListHandle&lt;Gtk::Widget*&gt;</classname>: Χρησιμοποιήστε<classname>std::vector&lt;Gtk::Widget*&gt;</classname>, <classname>std::list&lt;Gtk::Widget*&gt;</classname>, etc.Η <classname>Glib::RefPtr</classname> είναι ένας έξυπνος δείκτης. Ειδικά, είναι ένας έξυπνος δείκτης μετρητή αναφοράς. Μπορεί να είσαστε εξοικειωμένοι με τις <classname>std::auto_ptr&lt;&gt;</classname>, <classname>std::unique_ptr&lt;&gt;</classname> και <classname>std::shared_ptr&lt;&gt;</classname>, που είναι επίσης έξυπνοι δείκτες. Η <classname>Glib::RefPtr&lt;&gt;</classname> είναι παρόμοια με την <classname>std::shared_ptr&lt;&gt;</classname>, που είναι επίσης μετρητής αναφοράς. Η <classname>Glib::RefPtr&lt;&gt;</classname> εισήχθη πολύ πριν να υπάρξει ένα έξυπνο σημείο μετρητή αναφοράς στην τυπική βιβλιοθήκη C++.<classname>Glib::SListHandle&lt;Gtk::Widget*&gt;</classname>: Χρησιμοποιήστε <classname>std::vector&lt;Gtk::Widget*&gt;</classname>, <classname>std::list&lt;Gtk::Widget*&gt;</classname>, κλπ.<classname>Glib::StringArrayHandle</classname> or <classname>Glib::ArrayHandle&lt;Glib::ustring&gt;</classname>: Χρησιμοποιήστε <classname>std::vector&lt;Glib::ustring&gt;</classname>, <classname>std::list&lt;Glib::ustring&gt;</classname>, <type>const char*[]</type>, κλπ.Οι <classname>Gtk::Adjustment</classname>, <classname>IconSet</classname> και <classname>Gdk::Cursor</classname> χρησιμοποιούνται τώρα μέσα από <classname>Glib::RefPtr</classname>.Οι <classname>Gtk::AppChooser</classname>, <classname>Gtk::AppChooserButton</classname>, <classname>Gtk::AppChooserDialog</classname> επιτρέπουν την επιλογή μιας εγκατεστημένης εφαρμογής που θα ανοίξει έναν συγκεκριμένο τύπο περιεχομένου.Η <classname>Gtk::Box</classname> τακτοποιεί τα θυγατρικά της γραφικά συστατικά κάθετα ή οριζόντια. Χρησιμοποιήστε <methodname>pack_start()</methodname> και <methodname>pack_end()</methodname> για εισαγωγή θυγατρικών γραφικών συστατικών.Οι <classname>Gtk::Box</classname>, <classname>Gtk::ButtonBox</classname>, <classname>Gtk::IconView</classname>, <classname>Gtk::Paned</classname>, <classname>Gtk::ProgressBar</classname>, <classname>Gtk::ScaleButton</classname>, <classname>Gtk::Scrollbar</classname> και <classname>Gtk::Separator</classname> παράγονται τώρα από <classname>Gtk::Orientable</classname>, επιτρέποντας τον προσανατολισμό τους (κάθετο ή οριζόντιο) να οριστεί χωρίς αίτηση χρήσης παράγωγης κλάσης όπως <classname>Gtk::HBox</classname>.Η <classname>Gtk::Builder</classname> πρέπει να χρησιμοποιηθεί μέσα από μια <classname>Glib::RefPtr</classname>. Όπως όλες οι τέτοιες κλάσεις, χρειάζεται να χρησιμοποιήσετε μια μέθοδο <methodname>create()</methodname> για τη δημιουργία του. Για παράδειγμα, <placeholder-1/> Αυτό θα δημιουργήσει τα παράθυρα που ορίστηκαν στο αρχείο .glade, αν και δεν θα εμφανιστούν αμέσως, εκτός και το έχετε ορίσει μέσα από το παράθυρο <guilabel>Properties</guilabel> στην <application>Glade</application>.Η <classname>Gtk::Button</classname> είναι επίσης ένας περιέκτης, έτσι μπορείτε να βάλετε οποιοδήποτε άλλο γραφικό συστατικό, όπως μια <classname>Gtk::Image</classname> μέσα του.<classname>Gtk::CellLayout</classname>, χρησιμοποιήθηκε από <classname>Gtk::IconView</classname>, <classname>Gtk::TreeView::Column</classname> και <classname>Gtk::ComboBox</classname>, τώρα έχει μια <classname>Gtk::CellArea</classname> που μπορεί να χρησιμοποιηθεί για να ορίσει περισσότερες λεπτομέρειες τακτοποίησης και στοίχισης των <classname>CellRenderer</classname>.Η <classname>Gtk::CheckButton</classname> κληρονομεί από την <classname>Gtk::ToggleButton</classname>. Η μόνη πραγματική διαφορά μεταξύ των δύο είναι η εμφάνιση της <classname>Gtk::CheckButton</classname>. Μπορείτε να ελέγξετε, να ορίσετε και να εναλλάξετε ένα πλαίσιο ελέγχου χρησιμοποιώντας τις ίδιες μεθόδους μέλους όπως για την <classname>Gtk::ToggleButton</classname>.Η <classname>Gtk::Grid</classname> τακτοποιεί τα θυγατρικά της γραφικά συστατικά σε γραμμές και στήλες. Χρησιμοποιήστε <methodname>attach()</methodname>, <methodname>attach_next_to()</methodname> και <methodname>add()</methodname> για την εισαγωγή θυγατρικών γραφικών συστατικών.Η <classname>Gtk::Grid</classname> είναι ένα νέο γραφικό συστατικό περιέκτη που θα αντικαταστήσει τελικά την <classname>Gtk::Box</classname> και την <classname>Gtk::Table</classname>. Ταξινομεί τα θυγατρικά της σύμφωνα με τις ιδιότητες αυτών των θυγατρικών αντί για τις δικές της λεπτομέρειες διάταξης.<classname>Gtk::IconView</classname>, <classname>Gtk::TextView</classname>, <classname>Gtk::TreeView</classname> και άλλα γραφικά συστατικά παράγονται από κυλιόμενα αντί να έχουν τις δικές τους μεθόδους όπως <methodname>get_vadjustment()</methodname> και αντί να έχουν το δικό τους σήμα set_scroll_adjustments.Οι <classname>Gtk::Scale</classname> και <classname>Gtk::Scrollbar</classname> κληρονομούν από <classname>Gtk::Range</classname> και μοιράζονται πολλή λειτουργικότητα. Περιέχουν έναν "περιέκτη" και έναν "ολισθητή" (μερικές φορές λέγεται "ιχνοσφαίρα" σε άλλα περιβάλλοντα γραφικής διεπαφής. Σύροντας τον ολισθητή με τον δείκτη τον μετακινεί μέσα στον περιέκτη, ενώ πατώντας στον περιέκτη προωθεί τον ολισθητή προς τη θέση του πατήματος, είτε πλήρως, ή με υποδεικνυόμενη ποσότητα, ανάλογα με το ποιο πλήκτρο του ποντικιού χρησιμοποιείται. Αυτό πρέπει να εξοικειωθεί με τη συμπεριφορά της γραμμής κύλισης.Τα γραφικά συστατικά (ή "ολισθητές") <classname>Gtk::Scale</classname> επιτρέπουν στον χρήστη την οπτική επιλογή και χειρισμό μιας τιμής μέσα σε μια συγκεκριμένη περιοχή. Μπορεί να χρησιμοποιήσετε, για παράδειγμα, για να προσαρμόσετε το επίπεδο μεγέθυνσης σε μια εστιασμένη προεπισκόπηση μιας εικόνας, ή να ελέγξετε τη φωτεινότητα ενός χρώματος, ή να ορίσετε τον αριθμό των λεπτών αδράνειας πριν μια προφύλαξη οθόνης αναλάβει την οθόνη.Οι <classname>Gtk::Style</classname> and <classname>Gtk::Rc</classname> αφαιρέθηκαν και αντικαταστάθηκαν με <classname>Gtk::StyleContext</classname> και <classname>Gtk::StyleProvider</classname>s, όπως <classname>Gtk::CssProvider</classname>.Η <classname>Gtk::Switch</classname> εμφανίζει καταστάσεις ναι/όχι πιο σαφώς από την <classname>Gtk::CheckBox</classname>. Μπορεί να είναι χρήσιμη, για παράδειγμα, όταν επιτρέπει στους χρήστες να ενεργοποιούν υλικό.Η <classname>Gtk::Table</classname> επιτρέπει την τοποθέτηση γραφικών συστατικών σε ένα πλέγμα, παρόμοιο με <classname>Gtk::Grid</classname>.Η <classname>Gtk::Table</classname> είναι παρωχημένη από την έκδοση 3.4 της <application>gtkmm</application> και δεν πρέπει να χρησιμοποιηθεί σε νέο κώδικα. Χρησιμοποιήστε <classname>Gtk::Grid</classname> στη θέση του.Τα αντικείμενα <classname>Gtk::TargetEntry</classname> περιέχουν αυτήν την πληροφορία: <placeholder-1/><classname>Gtk::TextBuffer</classname> είναι ένα πρότυπο που περιέχει τα δεδομένα για την <classname>Gtk::TextView</classname>, όπως η <classname>Gtk::TreeModel</classname> χρησιμοποιείται από <classname>Gtk::TreeView</classname>. Αυτό επιτρέπει δύο ή περισσότερες <classname>Gtk::TextView</classname>s να μοιραστούν την ίδια <classname>TextBuffer</classname> και επιτρέπει αυτά τα TextBuffers να εμφανίζονται ελαφρά διαφορετικά. Ή μπορείτε να διατηρήσετε αρκετές <classname>Gtk::TextBuffer</classname>s και να επιλέξετε να εμφανίσετε κάθε μια σε διαφορετικούς χρόνους στο ίδιο γραφικό συστατικό <classname>Gtk::TextView</classname>.Η <classname>Gtk::TextView</classname> έχει ποικίλες μεθόδους <methodname>scroll_to_*()</methodname>. Αυτές επιτρέπουν να εξασφαλίσετε ότι το συγκεκριμένο μέρος της ενδιάμεσης μνήμης του κειμένου είναι ορατό. Για παράδειγμα, το γνώρισμα εύρεσης της εφαρμογή σας μπορεί να χρησιμοποιήσει την <methodname>Gtk::TextView::scroll_to_iter()</methodname> για να εμφανίσει το ευρεθέν κείμενο.Η <classname>Gtk::ToggleButton</classname> είναι η πιο χρήσιμη ως βασική κλάση για τις κλάσεις <classname>Gtk::CheckButton</classname> και <classname>Gtk::RadioButton</classname>.Οι <classname>Gtk::ToolItem</classname>s μπορούν έπειτα να προστεθούν στην ομάδα. Για παράδειγμα, ως εξής:Η <classname>Gtk::TreeModel</classname> παρέχει έναν τυπικό περιέκτη τεχνοτροπίας βιβλιοθήκης του θυγατρικού του, μέσα από τη μέθοδο <methodname>children()</methodname>. Μπορείτε να χρησιμοποιήσετε τις οικείες μεθόδους <methodname>begin()</methodname> and <methodname>end()</methodname> επαναλήπτη αύξησης, ως εξής:Τα πρότυπα <classname>Gtk::TreeStore</classname> μπορούν να έχουν θυγατρικά στοιχεία. Προσθέστε τα με τις μεθόδους <methodname>append()</methodname>, <methodname>prepend()</methodname>, ή <methodname>insert()</methodname> ως εξής:Η <classname>Gtk::TreeView</classname> υλοποιεί ήδη απλή μεταφορά και απόθεση όταν χρησιμοποιείται με τα μοντέλα <classname>Gtk::ListStore</classname> ή <classname>Gtk::TreeStore</classname>. Αν είναι απαραίτητο, επιτρέπει επίσης την υλοποίηση πιο σύνθετης συμπεριφοράς όταν μεταφέρονται και αποτίθενται στοιχεία, χρησιμοποιώντας την κανονική API <link linkend="chapter-draganddrop">Μεταφορά και απόθεση</link>.Η <classname>Gtk::Widget</classname> έχει αρκετές μεθόδους και σήματα με πρόθεμα "drag_". Αυτά χρησιμοποιούνται για μεταφορά και απόθεση.Η <classname>Menus</classname> προστέθηκε κανονικά μόλις σε ένα παράθυρο, αλλά μπορεί επίσης να εμφανιστεί προσωρινά ως το αποτέλεσμα ενός πατήματος πλήκτρου του ποντικιού. Για παράδειγμα, ένα μενού περιεχομένων μπορεί να εμφανιστεί όταν ο χρήστης πατά το δεξιό πλήκτρο ποντικιού.Η <classname>MessageDialog</classname> είναι μια κλάση διευκόλυνσης, που χρησιμοποιείται για τη δημιουργία απλών, τυπικών διαλόγων μηνύματος, με ένα μήνυμα, ένα εικονίδιο και κουμπιά για απάντηση του χρήστη. Μπορείτε να ορίσετε τον τύπο του μηνύματος και το κείμενο στον κατασκευαστή, καθώς και να ορίσετε τυπικά κουμπιά μέσα από την αρίθμηση <literal>Gtk::ButtonsType</literal>.Τα <classname>RadioButtons</classname> είναι "ανενεργά" όταν δημιουργούνται· αυτό σημαίνει ότι όταν κάνετε πρώτα μια ομάδα τους, θα είναι όλα ανενεργά. Μην παραλείψετε να ενεργοποιήσετε ένα τους χρησιμοποιώντας <methodname>set_active()</methodname>:Τα γραφικά συστατικά <classname>Range</classname> συνδέουν τυπικά έναν χειριστή με αυτό το σήμα, που αλλάζει την εμφάνισή τους για να απεικονίζει την αλλαγή - για παράδειγμα, το μέγεθος του ολισθητή σε μια γραμμή κύλισης θα αυξήσει ή θα συρρικνώσει αντιστρόφως ανάλογα με τη διαφορά μεταξύ των τιμών <parameter>lower</parameter> και <parameter>upper</parameter> της <classname>Adjustment</classname> του.Η <classname>RecentChooser</classname> είναι μια διεπαφή που μπορεί να υλοποιηθεί από γραφικά συστατικά που εμφανίζουν τον κατάλογο των πρόσφατα χρησιμοποιημένων αρχείων. Η <application>gtkmm</application> δίνει τέσσερις ενσωματωμένες υλοποιήσεις για επιλογή πρόσφατων αρχείων: <classname>RecentChooserWidget</classname>, <classname>RecentChooserDialog</classname>, <classname>RecentChooserMenu</classname> και <classname>RecentAction</classname>.Οι <classname>RecentChooserMenu</classname> και <classname>RecentAction</classname> επιτρέπουν την καταγραφή πρόσφατα χρησιμοποιημένων αρχείων ως μενού.Η <classname>RecentChooserWidget</classname> είναι ένα απλό γραφικό συστατικό για εμφάνιση ενός καταλόγου των πρόσφατα χρησιμοποιημένων αρχείων. Η <classname>RecentChooserWidget</classname> είναι η βασική ομάδα δόμησης για την <classname>RecentChooserDialog</classname>, αλλά μπορείτε να την ενσωματώσετε στη διεπαφή χρήστη αν θέλετε.Η <classname>RecentManager</classname> δρα ως μια βάση δεδομένων των πρόσφατα χρησιμοποιημένων αρχείων. Χρησιμοποιείτε αυτήν την κλάση για να καταχωρίσετε νέα αρχεία, να αφαιρέσετε αρχεία από τον κατάλογο, ή να αναζητήσετε πρόσφατα χρησιμοποιημένα αρχεία. Υπάρχει ένας κατάλογος των πρόσφατα χρησιμοποιημένων αρχείων ανά χρήστη.Η <classname>RecentManager</classname> είναι το πρότυπο ενός υποδείγματος προβολής προτύπου, όπου η προβολή είναι μια κλάση που υλοποιεί τη διεπαφή <classname>RecentChooser</classname>.Τα γραφικά συστατικά <classname>Scale</classname> μπορούν να εμφανίσουν την τρέχουσα τιμή τους ως έναν αριθμό δίπλα στον περιέκτη. Από προεπιλογή, εμφανίζουν την τιμή, αλλά μπορείτε να το αλλάξετε με τη μέθοδο <methodname>set_draw_value()</methodname>.Τα γραφικά συστατικά <classname>ScrolledWindow</classname> δημιουργούν μια κυλιόμενη περιοχή. Μπορείτε να εισάγετε οποιοδήποτε τύπο γραφικού συστατικού στο παράθυρο <classname>ScrolledWindow</classname> και θα είναι προσβάσιμο ανεξάρτητα από το μέγεθος του χρησιμοποιώντας τις γραμμές κύλισης. Σημειώστε ότι το <classname>ScrolledWindow</classname> δεν είναι μια <classname>Gtk::Window</classname> παρά το ελαφρώς παραπλανητικό όνομα.Οι <classname>SpinButton</classname>s χρησιμοποιούν ένα αντικείμενο <link linkend="chapter-adjustment">Adjustment</link> για να κρατήσουν πληροφορίες για την περιοχή των τιμών. Αυτά τα γνωρίσματα της ρύθμισης χρησιμοποιούνται από κουμπί αυξομείωσης όπως το: <placeholder-1/>Οι επαναλήπτες <classname>TextBuffer</classname> είναι γενικά άκυροι όταν το κείμενο αλλάζει, αλλά μπορείτε να χρησιμοποιήσετε μια <classname>Gtk::TextBuffer::Mark</classname> για να θυμάται μια θέση σε αυτές τις καταστάσεις. Για παράδειγμα,Η <classname>TextView</classname> έχει ποικίλες μεθόδους που επιτρέπουν την αλλαγή της παρουσίασης της ενδιάμεσης μνήμης για αυτήν τη συγκεκριμένη προβολή. Μερικές από αυτές μπορεί να αντικατασταθούν από τις <classname>Gtk::TextTag</classname>s στην ενδιάμεση μνήμη, αν ορίζουν τα ίδια πράγματα. Για παράδειγμα, <methodname>set_left_margin()</methodname>, <methodname>set_right_margin()</methodname>, <methodname>set_indent()</methodname>, κλπ.Οι <classname>ToggleButton</classname> είναι όπως τα κανονικά <classname>Button</classname>, αλλά όταν πατιούνται παραμένουν ενεργοποιημένα, ή πατημένα, μέχρι να ξαναπατηθούν.Οι <classname>ToolItemGroup</classname>s πρέπει να προστεθούν στη παλέτα του εργαλείου μέσα από τη μέθοδο <function>Gtk::Container::add()</function> της βασικής κλάσης, για παράδειγμα ως εξής:Η <classname>Widget</classname>s μπορεί να ταυτοποιηθεί ως πηγές ή προορισμοί χρησιμοποιώντας αυτές τις μεθόδους <classname>Gtk::Widget</classname>:Η <command>gmmproc</command> επιτρέπει την επεξεργασία παραμέτρων στην υπογραφή μιας μεθόδου για τις μακροεντολές που επεξεργάζονται τις υπογραφές μεθόδων (όπως <function>_WRAP_METHOD()</function>, <function>_WRAP_CTOR()</function> και <function>_WRAP_CREATE()</function>) με ποικιλία τρόπων:Η <command>gmmproc</command> θα προειδοποιήσει για την τυπική έξοδο σχετικά με τις συναρτήσεις και τα σήματα που έχετε ξεχάσει να συσκευάσετε, βοηθώντας την εξασφάλιση ότι συσκευάζετε την πλήρη API. Αλλά αν δεν θέλετε να συσκευάσετε κάποιες συναρτήσεις ή σήματα, ή αν διαλέξετε κώδικα με το χέρι μερικές μεθόδους, τότε μπορείτε να χρησιμοποιήσετε την μακροεντολή _IGNORE() or _IGNORE_SIGNAL() για να σταματήσετε να παραπονιέται η <command>gmmproc</command>.<filename>libsomething</filename>: Περιέχει το κύριο αρχείο συμπερίληψης και το αρχείο pkg-config .pc.<filename>libsomethingmm</filename>: Περιέχει δημιουργούμενα και χειρόγραφα αρχεία .h και .cc.<filename>libsomethingmm</filename>: Ο κατάλογος ανωτάτου επιπέδου.<filename>private</filename>: Περιέχει δημιουργούμενα αρχεία <filename>*_p.h</filename>.<filename>src</filename>: Περιέχει τα πηγαία αρχεία .hg και .ccg.Η <function>_WRAP_METHOD()</function> υποστηρίζει επίσης τον ορισμό παραμέτρων εξόδου C++ από παραμέτρους εξόδου C, αν η συνάρτηση C που συσκευάζεται έχει κάποια. Ας υποθέσουμε, για παράδειγμα, ότι θέλουμε να συσκευάσουμε την παρακάτω συνάρτηση C που επιστρέφει μια τιμή στην παράμετρο εξόδου της C <parameter>rect</parameter>: <placeholder-1/> Για να τοποθετηθεί η <command>gmmproc</command> στην επιστρεφόμενη τιμή από την παράμετρο εξόδου της C++ <parameter>rect</parameter>, κάτι όπως η ακόλουθη εντολή <function>_WRAP_METHOD()</function> μπορεί να χρησιμοποιηθεί: <placeholder-2/> Η <literal>{&gt;&gt;}</literal> ακολουθώντας το όνομα παραμέτρου <parameter>rect</parameter> δείχνει ότι η παράμετρος εξόδου C++ πρέπει να οριστεί από την επιστρεφόμενη τιμή στην παράμετρο C από τη συνάρτηση C. Η <command>gmmproc</command> θα δημιουργήσει μια δήλωση μιας προσωρινής μεταβλητής στην οποία θα αποθηκευτεί η τιμή της παραμέτρου εξόδου C και μια δήλωση που ορίζει την παράμετρο εξόδου C++ από την προσωρινή μεταβλητή. Σε αυτήν την περίπτωση μπορεί να είναι απαραίτητο να έχετε μια <function>_INITIALIZATION()</function> που περιγράφει πώς να οριστεί μια <classname>Gdk::Rectangle&amp;</classname> από μια <classname>GdkRectangle*</classname> όπως η ακόλουθη: <placeholder-3/><function>_WRAP_METHOD()</function>, <function>_WRAP_SIGNAL()</function> και <function>_WRAP_PROPERTY()</function>Η <function>sigc::bind()</function> δεν χρησιμοποιείται συνήθως, αλλά μπορείτε να την βρείτε χρήσιμη μερικές φορές. Αν είσαστε εξοικειωμένος με τον προγραμματισμό της <application>GTK+</application>, τότε θα έχετε προφανώς σημειώσει ότι αυτό είναι παρόμοιο με τα πρόσθετα ορίσματα <literal>gpointer data</literal> που όλα έχουν επανακλήσεις GTK+. Αυτό γενικά υπερχρησιμοποιείται στην <application>GTK+</application> για το πέρασμα πληροφοριών που πρέπει να αποθηκευτούν ως μέλη δεδομένων σε ένα παράγωγο γραφικό συστατικό, αλλά μια παραγωγή γραφικού συστατικού είναι πολύ δύσκολη στη C. Έχουμε πολύ λιγότερη ανάγκη αυτής της επέμβασης στην <application>gtkmm</application>.Η <function>sigc::ptr_fun()</function> δημιουργεί μια <classname>sigc::slot</classname>. Μια υποδοχή είναι ένα αντικείμενο που φαίνεται και αισθάνεται όπως μια συνάρτηση, αλλά στην πραγματικότητα είναι ένα αντικείμενο. Αυτά είναι επίσης γνωστά ως αντικείμενα συνάρτησης, ή functors. Η <function>sigc::ptr_fun()</function> δημιουργεί μια υποδοχή για μια αυτόνομη συνάρτηση ή στατική μέθοδο. Η <function>sigc::mem_fun()</function> δημιουργεί μια υποδοχή για μια μέθοδο μέλους ενός ιδιαίτερου στιγμιότυπου.Η <literal>$3</literal> θα αντικατασταθεί από το όνομα παραμέτρου εξόδου της μεθόδου C++ και η <literal>$4</literal> θα αντικατασταθεί από την επιστροφή της συνάρτησης C όταν αυτή η αρχικοποίηση χρησιμοποιείται από την gmmproc. Για ευκολία, η <literal>$1</literal> θα αντικατασταθεί επίσης από τον τύπο C++ χωρίς το συμπλεκτικό (&amp;) και η <literal>$2</literal> θα αντικατασταθεί από τον τύπο C.Η <literal>$3</literal> θα αντικατασταθεί από το όνομα παραμέτρου όταν αυτή η μετατροπή χρησιμοποιείται από την gmmproc.<literal>Gtk::PACK_EXPAND_PADDING</literal>: Ο πρόσθετος χώρος γεμίζεται με συμπλήρωση. Τα γραφικά συστατικά θα τοποθετηθούν ομοιόμορφα, αλλά τα μεγέθη τους δεν θα αλλάξουν - θα υπάρχει κενός χώρος μεταξύ των γραφικών συστατικών.<literal>Gtk::PACK_EXPAND_WIDGET</literal>: Ο πρόσθετος χώρος καταλαμβάνεται με αύξηση του μεγέθους του θυγατρικού γραφικού συστατικού, χωρίς αλλαγή του χώρου μεταξύ των γραφικών συστατικών.<literal>Gtk::PACK_SHRINK</literal>: Ο χώρος συμπτύσσεται στο μέγεθος του θυγατρικού γραφικού συστατικού. Το γραφικό συστατικό θα πάρει μόνο αρκετό χώρο και δεν θα επεκταθεί ποτέ.<literal>Gtk::UPDATE_CONTINUOUS</literal> - Αυτό είναι η προεπιλογή. Το σήμα <literal>value_changed</literal> εκπέμπεται συνεχώς, δηλαδή όποτε ο ολισθητής μετακινείται ακόμα και κατά το πιο μικρό ποσό.<literal>Gtk::UPDATE_DELAYED</literal> - Το σήμα <literal>value_changed</literal> εκπέμπεται όταν ο χρήστης ελευθερώσει το πλήκτρο του ποντικιού, ή αν ο ολισθητής σταματήσει τη μετακίνηση για μια σύντομη περίοδο του χρόνου.<literal>Gtk::UPDATE_DISCONTINUOUS</literal> - Το σήμα <literal>value_changed</literal> εκπέμπεται μόνο μόλις ο ολισθητής έχει σταματήσει τη μετακίνηση και ο χρήστης έχει ελευθερώσει το πλήκτρο του ποντικιού.Το <literal>LINGUAS</literal> περιέχει έναν αλφαβητικά ταξινομημένο κατάλογο κωδίκων που αναγνωρίζει τις γλώσσες για τις οποίες το πρόγραμμά σας μεταφράζεται (γραμμές σχολιασμού που ξεκινούν με ένα <literal>#</literal> αγνοούνται). Κάθε καταχωρισμένος κωδικός γλώσσας στο αρχείο <literal>LINGUAS</literal> πρέπει να έχει ένα αντίστοιχο αρχείο <literal>.po</literal>. Έτσι, αν το πρόγραμμά σας έχει γερμανική και ιαπωνική μετάφραση, το αρχείο σας <literal>LINGUAS</literal> θα μοιάζει ως εξής:Το <literal>POTFILES.in</literal> είναι ένας κατάλογος διαδρομών σε όλα τα αρχεία που περιέχουν συμβολοσειρές σημειωμένες για μετάφραση, ξεκινώντας από τον ριζικό κατάλογο του έργου. Έτσι, για παράδειγμα, αν οι πηγές του έργου σας είναι σε έναν υποκατάλογο με όνομα <literal>src</literal> και έχετε δύο αρχεία που περιέχουν συμβολοσειρές που πρέπει να μεταφραστούν, το αρχείο <literal>POTFILES.in</literal> μπορεί να μοιάζει ως εξής:Οι <literal>actions</literal> δείχνουν τις ενέργειες μεταφοράς και απόθεσης που αυτός ο προορισμός μπορεί να δεχτεί - δείτε την παραπάνω περιγραφή.<literal>actions</literal> είναι ένας συνδυασμός τιμών ORed, που ορίζει ποιες λειτουργίες μεταφοράς και απόθεσης θα είναι δυνατές από αυτήν την πηγή - για παράδειγμα, αντιγραφή, μετακίνηση, ή σύνδεση. Ο χρήστης μπορεί να επιλέξει μεταξύ των ενεργειών χρησιμοποιώντας πλήκτρα τροποποίησης, όπως <keycap>Shift</keycap> για αλλαγή από <literal>copy</literal> σε <literal>move</literal> και αυτό θα εμφανιστεί από έναν διαφορετικό δρομέα.<literal>begin_print</literal>: Πρέπει να χειριστείτε αυτό το σήμα, επειδή εκεί δημιουργείται και ρυθμίζεται μια <classname>Pango::Layout</classname> χρησιμοποιώντας της παρεχόμενη <classname>Gtk::PrintContext</classname> και διασπά την έξοδο που εκτυπώνεται σε σελίδες.<literal>done</literal>: Αυτό το σήμα εκπέμπεται όταν τελειώσει η εκτύπωση, που σημαίνει όταν τα δεδομένα της εκτύπωσης έχουν μπει στην ουρά. Σημειώστε ότι η παρεχόμενη <literal>Gtk::PrintOperationResult</literal> μπορεί να δείξει ότι προέκυψε ένα σφάλμα. Σε κάθε περίπτωση θα θέλετε προφανώς να ειδοποιήσετε τον χρήστη για την τελική κατάσταση.<literal>drag_begin</literal>: παρέχει DragContext.<literal>drag_data_delete</literal>: Δίνει στην προέλευση την ευκαιρία να διαγράψει τα αρχικά δεδομένα αν αυτό είναι σωστό.<literal>drag_data_get</literal>: Παρέχει <literal>info</literal> για την μορφή μεταφερόμενων δεδομένων και μια δομή <literal>Gtk::SelectionData</literal>, στην οποία θα πρέπει να βάλετε τα ζητούμενα δεδομένα.<literal>drag_data_received</literal>: Παρέχει <literal>info</literal> για τη μορφή μεταφερόμενων δεδομένων και μια δομή <literal>Gtk::SelectionData</literal> που περιέχει τα αποτιθέμενα δεδομένα. Θα πρέπει να καλέσετε τη μέθοδο <methodname>drag_finish()</methodname> της <literal>DragContext</literal> για να δείξετε αν η λειτουργία ήταν πετυχημένη.<literal>drag_drop</literal>: Παρέχει το DragContext και τις συντεταγμένες. Μπορείτε να καλέσετε την <methodname>drag_get_data()</methodname>, που διεγείρει το σήμα <literal>drag_data_get</literal> στο γραφικό συστατικό προέλευσης και έπειτα το σήμα <literal>drag_data_received</literal> στο γραφικό συστατικό προορισμού.<literal>drag_end</literal>: Παρέχει DragContext.<literal>drag_motion</literal>: Παρέχει την DragContext και συντεταγμένες. Μπορείτε να καλέσετε τη μέθοδο <methodname>drag_status()</methodname> της DragContext για να δείξετε ποια ενέργεια θα δεχτεί.<literal>draw_page</literal>: Πρέπει να χειριστείτε αυτό το σήμα, που δίνει μια <classname>PrintContext</classname> και έναν αριθμό σελίδας. Η <classname>PrintContext</classname> πρέπει να χρησιμοποιηθεί για τη δημιουργία μιας <classname>Cairo::Context</classname> στην οποία η παρεχόμενη σελίδα πρέπει να σχεδιαστεί. Για απόδοση κειμένου, επαναλάβετε την <classname>Pango::Layout</classname> που δημιουργήσατε στον χειριστή <literal>begin_print</literal>.<literal>end_print</literal>: Ένας χειριστής για μια ασφαλή θέση για να ελευθερώσει κάθε πόρο σχετικό με μια <classname>PrintOperation</classname>. Αν έχετε την προσαρμοσμένη κλάση σας που κληρονομεί από την <classname>PrintOperation</classname>, είναι φυσικά πιο απλό να το κάνετε στον καταστοφέα.Οι <literal>flags</literal> είναι ένας συνδυασμός τιμών ORed που δείχνει πώς θα απαντήσει οπτικά το γραφικό συστατικό σε στοιχεία μεταφοράς και απόθεσης.<literal>lower</literal>: μικρότερη τιμή περιοχής<literal>page_increment</literal>: η τιμή για αύξηση/μείωση όταν πατιέται το πλήκτρου του ποντικιού 2 σε ένα κουμπί<literal>page_size</literal>: αχρησιμοποίητο<literal>paginate</literal>: Η σελιδοποίηση είναι δυνητικά αργή, έτσι αν χρειάζεται να την παρακολουθήσετε μπορείτε να καλέσετε τη μέθοδο <methodname>PrintOperation::set_show_progress()</methodname> και να χειριστείτε αυτό το σήμα.<literal>request_page_setup</literal>: Δίνει μια <classname>PrintContext</classname>, αριθμό σελίδας και <classname>Gtk::PageSetup</classname>. Χειριστείτε αυτό το σήμα αν χρειάζεστε να τροποποιήσετε τη διαμόρφωση της σελίδας σε βάση ανά σελίδα.<literal>start_button_mask</literal> είναι ένας συνδυασμός τιμών ORed, που ορίζει ποιο πλήκτρο τροποποίησης ή πλήκτρο του ποντικιού πρέπει να πατηθεί για να ξεκινήσει η μεταφορά.<literal>status_changed</literal>: Εκπέμπεται όποτε η κατάσταση μιας δουλειάς εκτύπωσης αλλάζει, μέχρι να τελειώσει. Καλέστε τη μέθοδο <methodname>PrintOperation::set_track_print_status()</methodname> να παρακολουθεί την κατάσταση της εργασίας μετά την τοποθέτηση στην ουρά της εκτύπωσης. Για να δείτε την κατάσταση, χρησιμοποιήστε την <methodname>get_status()</methodname> ή την <methodname>get_status_string()</methodname>.<literal>step_increment</literal>: η τιμή για αύξηση/μείωση όταν πατιέται το πλήκτρου του ποντικιού 1 σε ένα κουμπίΤο <literal>targets</literal> είναι ένα διάνυσμα των στοιχείων <classname>Gtk::TargetEntry</classname>.<literal>lower</literal>: μεγαλύτερη τιμή περιοχής<literal>value</literal>: η τιμή για το κουμπί αυξομείωσηςΗ <methodname>Gtk::Widget::show()</methodname> επιτρέπει στην <application>gtkmm</application> να ξέρει ότι έχουμε τελειώσει τη ρύθμιση των γνωρισμάτων του γραφικού συστατικού και ότι είναι έτοιμο να εμφανιστεί. Μπορείτε να χρησιμοποιήσετε την <methodname>Gtk::Widget::hide()</methodname> για να το εξαφανίσετε πάλι. Η σειρά με την οποία εμφανίζετε τα γραφικά συστατικά δεν είναι σημαντική, αλλά προτείνουμε να δείξετε τελευταίο το παράθυρο ανωτάτου επιπέδου· έτσι, ολόκληρο το παράθυρο θα εμφανιστεί με τα περιεχόμενά του ήδη σχεδιασμένα. Αλλιώς, ο χρήστης θα δει πρώτα ένα κενό παράθυρο, στο οποίο τα γραφικά συστατικά θα σχεδιαστούν σταδιακά.Η <methodname>child_type_vfunc()</methodname>: Επιστρέφει ποιος τύπος θυγατρικού μπορεί να προστεθεί.Η <methodname>forall_vfunc()</methodname>: Καλεί την ίδια επανάκληση για κάθε θυγατρικό.Η <methodname>get_preferred_height_for_width_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό ύψος του περιέκτη, αν του δοθεί το συγκεκριμένο πλάτος.Η <methodname>get_preferred_height_for_width_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό ύψος του γραφικού συστατικού, αν του δοθεί το συγκεκριμένο πλάτος.Η <methodname>get_preferred_height_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό ύψος του περιέκτη.Η <methodname>get_preferred_height_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό ύψος του γραφικού συστατικού.Η <methodname>get_preferred_width_for_height_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό πλάτος του περιέκτη, αν του δοθεί το συγκεκριμένο ύψος.Η <methodname>get_preferred_width_for_height_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό πλάτος του γραφικού συστατικού, αν του δοθεί το συγκεκριμένο ύψος.Η <methodname>get_preferred_width_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό πλάτος του περιέκτη.Η <methodname>get_preferred_width_vfunc()</methodname>: Υπολογίζει το ελάχιστο και φυσικό πλάτος του γραφικού συστατικού.Η <methodname>get_request_mode_vfunc()</methodname>: (προαιρετικά) Επιστρέφει το <literal>Gtk::SizeRequestMode</literal> που προτιμάται από το γραφικό συστατικό.Η <methodname>get_request_mode_vfunc()</methodname>: Επιστρέφει το <literal>Gtk::SizeRequestMode</literal> που προτιμάται από τον περιέκτη.Η <methodname>get_widget()</methodname> επιστρέφει θυγατρικά γραφικά συστατικά που είναι <function>manage()</function>ed (δείτε το κεφάλαιο <link linkend="chapter-memory">Διαχείριση μνήμης</link>), έτσι θα διαγραφούν όταν ο γονικός τους περιέκτης διαγράφεται. Έτσι, αν πάρετε μόνο ένα θυγατρικό γραφικό συστατικό από την <application>Gtk::Builder</application>, αντί για ένα πλήρες παράθυρο, τότε πρέπει ή να το βάλετε σε έναν <classname>Container</classname> ή να το διαγράψετε. Η <classname>Windows</classname> (όπως η <classname>Dialogs</classname>) δεν μπορεί να διαχειριστεί, επειδή δεν έχουν γονικό περιέκτη, έτσι πρέπει να τα διαγράψετε σε κάποιο σημείο.Η <methodname>on_add()</methodname>: Προσθέτει ένα θυγατρικό γραφικό συστατικό στον περιέκτη.Η <methodname>on_draw()</methodname>: σχεδιάζει στην παρεχόμενη <classname>Cairo::Context</classname>.Η <methodname>on_map()</methodname>: (προαιρετικά)Η <methodname>on_realize()</methodname>: Συσχετίζει μια <classname>Gdk::Window</classname> με το γραφικό συστατικό.Η <methodname>on_remove()</methodname>: Αφαιρεί ένα θυγατρικό γραφικό συστατικό από τον περιέκτη.Η <methodname>on_size_allocate()</methodname> δέχεται το ενεργό ύψος και πλάτος που ο γονικός περιέκτης έχει αποφασίσει να δώσσει στο γραφικό συστατικό του. Αυτό μπορεί να είναι περισσότερο από το ελάχιστο, ή ακόμα περισσότερο από το φυσικό μέγεθος, για παράδειγμα αν το παράθυρο ανωτάτου επιπέδου έχει επεκταθεί. Μπορεί να επιλέξετε να αγνοήσετε τον πρόσθετο χώρο και να αφήσετε μια κενή περιοχή, ή μπορείτε να επιλέξετε να επεκτείνετε τα θυγατρικά γραφικά συστατικά σας για να γεμίσετε τον χώρο, ή να επεκτείνετε τη συμπλήρωση μεταξύ των γραφικών συστατικών σας. Είναι ο περιέκτης σας, έτσι αποφασίζετε. Να μην ξεχάσετε να καλέσετε την <methodname>set_allocation()</methodname> μέσα στην υλοποίησή σας <methodname>on_size_allocate()</methodname> για να χρησιμοποιήσετε στην πραγματικότητα τον κατανεμημένο χώρο που έχει προσφερθεί από τον γονικό περιέκτη.Η <methodname>on_size_allocate()</methodname>: Τοποθετεί τα θυγατρικά γραφικά συστατικά, με δεδομένα το ύψος και το πλάτος που έχει δοθεί στην πραγματικότητα στον περιέκτη.Η <methodname>on_size_allocate()</methodname>: Τοποθετεί το γραφικό συστατικό, με δεδομένα το ύψος και το πλάτος που έχουν δοθεί στην πραγματικότητα.Η <methodname>on_unmap()</methodname>: (προαιρετικά)Η <methodname>on_unrealize()</methodname>: (προαιρετικά) Διακόπτει τη σχέση με την <classname>Gdk::Window</classname>.Η <methodname>run()</methodname> μπορεί να επιστρέψει την <literal>PRINT_OPERATION_RESULT_IN_PROGRESS</literal>. Για ανίχνευση της κατάστασης και χειρισμό του αποτελέσματος ή σφάλματος χρειάζεται να υλοποιηθούν οι χειριστές σήματος για τα σήματα <literal>done</literal> και <literal>status_changed</literal>:<placeholder-1/> (ή <placeholder-2/> για ονόματα αρχείων)<placeholder-1/> Τώρα, όταν αντικείμενα του τύπου <classname>MyContainer</classname> καταστρέφονται, το πλήκτρο θα διαγραφεί επίσης. Δεν είναι πια απαραίτητο να διαγράψετε την <varname>pButton</varname> για να ελευθερώσετε τη μνήμη του πλήκτρου· η διαγραφή του έχει ανατεθεί στο αντικείμενο <classname>MyContainer</classname>.<placeholder-1/> πακέτο παραδείγματοςΟ <type>GdkEventButton</type> είναι μια δομή που περιέχει τις παραμέτρους του συμβάντος, όπως τις συντεταγμένες του δείκτη του ποντικιού την ώρα ποπυ το πλήκτρο πατήθηκε. Υπάρχουν αρκετοί διαφορετικοί τύποι δομών <type>GdkEvent</type> για τα ποικίλα συμβάντα.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1Button.html"><classname>Gtk::Button</classname></ulink>. Τυπικά κουμπιά, συνήθως σημειωμένα με μια ετικέτα ή εικόνα. Πιέζοντας ένα προκαλεί μια ενέργεια. Δείτε την ενότητα <link linkend="sec-pushbuttons">Κουμπί</link>.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1CheckButton.html"><classname>Gtk::CheckButton</classname></ulink>. Αυτά δρουν ως ToggleButtons, αλλά εμφανίζουν την κατάστασή τους σε μικρά τετράγωνα, με την ετικέτα τους στο πλάι. Πρέπει να χρησιμοποιούνται στις περισσότερες περιπτώσεις που απαιτούν μια ρύθμιση ναι/όχι. Δείτε την ενότητα <link linkend="sec-checkboxes">CheckBox</link>.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1RadioButton.html"><classname>Gtk::RadioButton</classname></ulink>. Ονομάστηκαν σύμφωνα με τους επιλογείς σταθμών σε παλιά ραδιόφωνα αυτοκινήτων, αυτά τα κουμπιά χρησιμοποιούνται σε ομάδες για επιλογές που αποκλείονται αμοιβαία. Πατώντας ένα προκαλεί όλα τα άλλα σε αυτήν την ομάδα να απενεργοποιηθούν. Είναι παρόμοια με τα CheckBoxes (ένα μικρό γραφικό συστατικό με μια ετικέτα στο πλάι), αλλά συνήθως μοιάζουν διαφορετικά. Δείτε την ενότητα <link linkend="sec-radio-buttons">RadioButton</link>.<ulink url="http://developer.gnome.org/gtkmm/unstable/classGtk_1_1ToggleButton.html"><classname>Gtk::ToggleButton</classname></ulink>. Αντίθετα με ένα κανονικό κουμπί, που αναπηδά πίσω, ένα ToggleButton παραμένει κάτω μέχρι να το ξαναπήσετε. Μπορεί να είναι χρήσιμο ως ένας διακόπτης ναι/όχι. Δείτε την ενότητα <link linkend="sec-toggle-buttons">ToggleButton</link>.<varname>app_exec</varname>: Η γραμμή εντολών που θα χρησιμοποιηθεί για εκκίνηση αυτού του πόρου. Αυτή η συμβολοσειρά μπορεί να περιέχει τους χαρακτήρες διαφυγής "f" και "u" που θα επεκταθούν στη διαδρομή αρχείου του πόρου και στο URI αντίστοιχα<varname>app_name</varname>: Το όνομα της εφαρμογής που καταχωρίστηκε στον πόρο<varname>description</varname>: Μια σύντομη περιγραφή του πόρου ως μια κωδικοποιημένη συμβολοσειρά UTF-8<varname>display_name</varname>: Το όνομα του πόρου που θα χρησιμοποιηθεί για εμφάνιση ως μιας κωδικοποιημένης συμβολοσειράς UTF-8<varname>groups</varname>: Ένας κατάλογος ομάδων που σχετίζεται με αυτό το στοιχείο. Οι ομάδες είναι βασικά ελεύθερες συμβολοσειρές που σχετίζονται με έναν συγκεκριμένο πόρο. Μπορούν να θεωρηθούν ως 'κατηγορίες' (όπως "αλληλογραφία", "γραφικά", κλπ) ή ετικέτες για τον πόρο.<varname>is_private</varname>: Αν αυτός ο πόρος πρέπει να είναι ορατός μόνο στις εφαρμογές που το έχουν καταχωρίσει ή όχι<varname>mime_type</varname>: Ο τύπος MIME του πόρουΈνα αρχείο .hg θα περιλαμβάνει τυπικά κάποιες κεφαλίδες και έπειτα θα δηλώνει μια κλάση, χρησιμοποιώντας μερικές μακροεντολές για να προσθέσει API ή συμπεριφορά σε αυτήν την κλάση. Για παράδειγμα, στην <application>gtkmm</application> και στο <filename>button.hg</filename> της φαίνεται χοντρικά ως εξής: <placeholder-1/>Μια <classname>ComboBox</classname> μπορεί να περιέχει ένα γραφικό συστατικό <classname>Entry</classname> για εισαγωγή ελεύθερου κειμένου, ορίζοντας <literal>true</literal> για την παράμετρο του κατασκευαστή <literal>has_entry</literal>.Ένα γραφικό συστατικό <classname>Entry</classname> μπορεί να προσφέρει μια πτυσσόμενη λίστα προϋπαρχουσών επιλογών με βάση τους πρώτους λίγους χαρακτήρες που πληκτρολογήθηκαν από τον χρήστη. Για παράδειγμα, ένας διάλογος αναζήτησης μπορεί να προτείνει κείμενο από προηγούμενες αναζητήσεις.Μια <classname>Glib::Dispatcher</classname> χρησιμοποιείται για αποστολή ειδοποιήσεων από το νήμα εργασίας στο νήμα GUI. Η κλάση <classname>ExampleWorker</classname> περιέχει δεδομένα που προσπελάζονται και από τα δύο νήματα. Αυτά τα δεδομένα προστατεύονται από μια <classname>Glib::Threads::Mutex</classname>. Μόνο το νήμα GUI ενημερώνει τη GUI.Ένα αντικείμενο <classname>Glib::Dispatcher</classname> μπορεί να εκπεμφθεί από το νήμα δέκτη καθώς και από το νήμα εργασίας, αν και αυτό πρέπει να γίνει μέσα σε λογικά όρια. Σε συστήματα Γιούνιξ και παρεμφερή τα αντικείμενα <classname>Glib::Dispatcher</classname> μοιράζονται μια μοναδική κοινή διοχέτευση, που μπορεί, τουλάχιστον θεωρητικά, να γεμίσει ένα πολύ έντονα φορτωμένο σύστημα που εκτελεί ένα πρόγραμμα με έναν πολύ μεγάλο αριθμό αντικειμένων <classname>Dispatcher</classname> σε χρήση. Αν η διοχέτευση γεμίσει πριν ο κύριος βρόχος του νήματος δέκτη είχε μια ευκαιρία να τον διαβάσει για να τον αδειάσει και το νήμα δέκτη προσπάθησε να εκπέμψει και έτσι να γράψει σε αυτό όταν είναι σε αυτήν την κατάσταση, το νήμα δέκτη μπορεί να φράξει την εγγραφή, έτσι αδιέξοδο. Όπου το νήμα δέκτη πρόκειται να εκπέμψει, ένα κανονικό αντικείμενο <classname>sigc::signal&lt;void&gt;</classname> μπορεί φυσικά να χρησιμοποιηθεί στη θέση του.Μια <classname>Grid</classname> διευθετεί δυναμικά τα θυγατρικά γραφικά συστατικά σε γραμμές και στήλες. Οι διαστάσεις του πλέγματος δεν χρειάζονται να οριστούν στον κατασκευαστή.Μια A <classname>Notebook</classname> έχει ένα σύνολο στοιβαγμένων <literal>pages</literal> (σελίδων), που καθεμιά τους περιέχει γραφικά συστατικά. Με ετικέτα <literal>tabs</literal> (καρτέλες) επιτρέπει στον χρήστη να επιλέξει τις σελίδες. Οι <classname>Notebook</classname>s επιτρέπουν αρκετά σύνολα γραφικών συστατικών να τοποθετηθούν σε μικρό χώρο, εμφανίζοντας μόνο μια σελίδα τη φορά. Για παράδειγμα, χρησιμοποιούνται συχνά σε διαλόγους προτιμήσεων.Μια <classname>Plug</classname> είναι ένα ειδικό είδος παραθύρου που μπορεί να συνδεθεί με μια <classname>Socket</classname>. Εκτός από τις κανονικές ιδιότητες και μεθόδους της <classname>Gtk::Window</classname>, μια <classname>Plug</classname> παρέχει έναν κατασκευαστή που παίρνει το αναγνωριστικό μιας <classname>Socket</classname>, που θα ενσωματώσει αυτόματα την <classname>Plug</classname> στην <classname>Socket</classname> που ταιριάζει αυτό το αναγνωριστικό.Μια <classname>ProgressBar</classname> είναι οριζόντια και από αριστερά προς τα δεξιά από προεπιλογή, αλλά μπορείτε να την αλλάξετε σε μια κάθετη γραμμή προόδου χρησιμοποιώντας τη μέθοδο <methodname>set_orientation()</methodname> method.Ένα αντικείμενο <classname>RecentInfo</classname> είναι βασικά ένα αντικείμενο που περιέχει όλα τα μεταδεδομένα για ένα μονό πρόσφατα χρησιμοποιούμενο αρχείο. Μπορείτε να χρησιμοποιήσετε αυτό το αντικείμενο για αναζήτηση οποιασδήποτε ιδιότητας είναι καταχωρισμένη <link linkend="list-file-metadata">παραπάνω</link>.Μια <classname>Socket</classname> είναι ένα ειδικό είδος γραφικού συστατικού περιέκτη που παρέχει την ικανότητα ενσωμάτωσης γραφικών συστατικών από μια διεργασία σε μια άλλη διεργασία με έναν τρόπο που είναι διαφανής στον χρήστη.Μια <classname>SpinButton</classname> επιτρέπει την επιλογή μιας τιμής από μια περιοχή αριθμητικών τιμών. Έχει ένα γραφικό συστατικό <classname>Entry</classname> με κουμπιά αύξησης και μείωσης στο πλάι. Πατώντας τα κουμπιά προκαλεί στην τιμή να 'αυξομειωθεί' μες την περιοχή των δυνατών τιμών. Το γραφικό συστατικό <classname>Entry</classname> μπορεί επίσης να χρησιμοποιηθεί για εισαγωγή μιας τιμής άμεσα.Μια <classname>ToolPalette</classname> είναι παρόμοια με μια <classname>Toolbar</classname>, αλλά μπορεί να περιέχει ένα πλέγμα στοιχείων, κατηγοριοποιημένο σε ομάδες. Ο χρήστης μπορεί να κρύψει ή να επεκτείνει κάθε ομάδα. Όπως στην εργαλειοθήκη, τα στοιχεία μπορεί να εμφανιστούν ως μόνο εικονίδια, ως μόνο κείμενο, ή ως εικονίδια με κείμενο.Ένα αντικείμενο <classname>sigc::signal</classname> πρέπει να θεωρείται ως κατεχόμενο από το νήμα που το δημιούργησε. Μόνο αυτό το νήμα συνδέει ένα αντικείμενο <classname>sigc::slot</classname> με το αντικείμενο σήματος και μόνο αυτό το νήμα πρέπει να <methodname>emit()</methodname> ή να καλεί την <methodname>operator()()</methodname> με το σήμα, ή να αδειάζει οποιοδήποτε συνδεμένο αντικείμενο <classname>sigc::slot</classname>. Ακολουθεί (μεταξύ άλλων) ότι οποιοδήποτε αντικείμενο σήματος που παρέχεται από το γραφικό συστατικό <application>gtkmm</application> πρέπει να λειτουργεί μόνο στο κύριο νήμα γραφικής διεπαφής χρήστη και οποιοδήποτε αντικείμενο παράγεται από την <classname>sigc::trackable</classname> να έχει τις μη στατικές μεθόδους του που αναφέρονται από τις συνδεμένες υποδοχές στο αντικείμενο σήματος που πρέπει να καταστραφεται μόνο σε αυτό το νήμα.Ένα αντικείμενο <classname>sigc::slot</classname> που δημιουργήθηκε από μια κλήση στην <function>sigc::mem_fun()</function> που αναφέρει μια μέθοδο μιας κλάσης που παράγεται από <classname>sigc::trackable</classname> δεν θα πρέπει ποτέ να αντιγραφεί σε άλλο νήμα, ή να καταστραφεί από διαφορετικό νήμα από αυτό που το δημιούργησε. (Μια συνέπεια αυτού είναι ότι η <methodname>Glib::Threads::Thread::create()</methodname> δεν πρέπει να κληθεί με ένα όρισμα υποδοχής που δημιουργήθηκε από μια κλήση της <function>sigc::mem_fun()</function> που αναπαριστά μια μέθοδο μιας τέτοιας κλάσης. Είναι όμως ασφαλές να περάσετε στην <methodname>Glib::Threads::Thread::create()</methodname> ένα αντικείμενο συνάρτησης που απεικονίζει μια τέτοια μέθοδο χρησιμοποιώντας <function>boost::bind()</function> ή, στην C++11, <function>std::bind()</function> ή μία έκφραση λάμδα C++11.)Ένα θυγατρικό γραφικό συστατικό μπορεί να προστεθεί στο <classname>EventBox</classname> χρησιμοποιώντας:Ένα μικρό παράδειγμα ακολουθεί. Για τη χρήση του παραδείγματος εκτελέστε το απλά από ένα τερματικό· δεν δημιουργεί παράθυρο. Θα δημιουργήσει μια διοχέτευση με όνομα <literal>testfifo</literal> στον τρέχοντα κατάλογο. Έπειτα ξεκινήστε ένα άλλο κέλυφος και εκτελέστε την <literal>echo "Hello" &gt; testfifo</literal>. Το παράδειγμα θα εκτυπώσει κάθε γραμμή που εισάγετε μέχρι την εκτέλεση της <literal>echo "Q" &gt; testfifo</literal>.Ένα αποτελεσματικό γνώρισμα του Glib (μια από τις βιβλιοθήκες που υπόκεινται στην <application>gtkmm</application>) είναι η ικανότητα να ελέγχουν για δεδομένα σε έναν περιγραφέα αρχείου για σας. Αυτό είναι ιδιαίτερα χρήσιμο για εφαρμογές δικτύωσης. Η παρακάτω μέθοδος χρησιμοποιείται για να κάνετε αυτό:Μια σωστά διεθνοποιημένη εφαρμογή δεν θα κάνει υποθέσεις για τον αριθμό των ψηφιολέξεων σε έναν χαρακτήρα. Αυτό σημαίνει ότι δεν πρέπει να χρησιμοποιείτε αριθμητικό δείκτη για να περιδιαβείτε τους χαρακτήρες σε μια συμβολοσειρά και σημαίνει ότι δεν πρέπει να χρησιμοποιήσετε <classname>std::string</classname> ή τυπικές συναρτήσεις C όπως <function>strlen()</function>, επειδή κάνουν την ίδια υπόθεση.Ένας κανόνας στον οποίον ενδέχεται να υπάρχουν εξαιρέσεις: Αν η εικονική συνάρτηση C επιστρέφει έναν δείκτη σε ένα αντικείμενο που παράγεται από την <classname>GObject</classname>, δηλαδή ένα αντικείμενο με μετρημένες αναφορές, τότε η εικονική συνάρτηση C++ θα επιστρέψει ένα αντικείμενο <classname>Glib::RefPtr&lt;&gt;</classname>. Ένα από τα πρόσθετα ορίσματα <parameter>refreturn</parameter> ή <parameter>refreturn_ctype</parameter> απαιτείται.Ένας έξυπνος δείκτης δρα παρόμοια με έναν κανονικό δείκτη. Ιδού μερικά παραδείγματα.Ένας προορισμός μπορεί να είναι σε μια ποικιλία δυαδικών μορφών. Αυτό το κεφάλαιο και τα παραδείγματα θεωρούν ότι τα δεδομένα είναι κείμενο 8 δυαδικών. Αυτό μπορεί να επιτρέψει τη χρήση μιας μορφής XML για τα δεδομένα του προχείρου. Όμως, αυτό μπορεί προφανώς να μην είναι κατάλληλο για δυαδικά δεδομένα όπως εικόνες. Η <classname>Gtk::Clipboard</classname> δίνει υπερφορτώσεις που επιτρέπουν τον ορισμό μορφής με περισσότερη λεπτομέρεια αν είναι απαραίτητο.AM_CPPFLAGSAM_CPPFLAGS = ... -DPROGRAMNAME_LOCALEDIR=\"${PROGRAMNAME_LOCALEDIR}\"AM_CXXFLAGSATKΠερί διαλόγου (AboutDialog)Πρόσβαση γραφικών συστατικώνΕνέργειεςΚατάσταση δραστηριότηταςΠροσθέστε το <literal>INTLTOOL_FILES</literal> στον κατάλογο αρχείων <literal>EXTRA_DIST</literal>. Αυτό διασφαλίζει ότι όταν κάνετε μια <command>make dist</command>, αυτές οι εντολές θα συμπεριληφθούν στο πηγαίο tarball.Προσθέστε <literal>po</literal> στη μεταβλητή <literal>SUBDIRS</literal>. Χωρίς αυτό, οι μεταφράσεις σας δεν θα δομηθούν και δεν θα εγκατασταθούν όταν δομείτε το πρόγραμμα.Προσθήκη προεπιλεγμένου κατασκευαστή.Προσθέστε μεθόδους για συσκευασία τμημάτων της API C.Προσθέστε γραμμές στο πρότυπο με τις μεθόδους <methodname>append()</methodname>, <methodname>prepend()</methodname>, ή <methodname>insert()</methodname>.Προσθήκη στοιχείων στον κατάλογο των πρόσφατων αρχείωνΠροσθήκη γραμμώνΠροσθήκη στηλών προβολήςΠροσθήκη θυγατρικών γραμμώνΗ προσθήκη ιδιοτήτων και η επιβεβαίωση ότι αλληλεπιδρούν σωστά μεταξύ τους, είναι σχετικά δύσκολο να διορθωθεί στη βιβλιοθήκη C, αλλά είναι δυνατή, έτσι στείλτε ένα σφάλμα και προσπαθήστε να στείλετε μια διόρθωση στον σχετικό συντηρητή.Προσθήκη γραφικών συστατικώνΟι πρόσθετες σημαίες της γραμμής εντολών που πέρασαν στο σενάριο <filename>generate_wrap_init.pl</filename>, όπως στον χώρο ονόματος C++ και το γονικό πρόθεμα καταλόγου των αρχείων συμπερίληψης.Επιπρόσθετα, το πλήκτρο του ποντικιού 3 μπορεί να χρησιμοποιηθεί για άμεση μετάβαση στις τιμές <literal>ανώτερη</literal> ή <literal>κατώτερη</literal>.Προσαρμογή εσωτερικώνΠροσαρμογέςΑφού ένα αντικείμενο <classname>Socket</classname> ή μια <classname>Plug</classname> πραγματοποιηθεί, μπορείτε να πάρετε το αναγνωριστικό του με τη συνάρτησή του <methodname>get_id()</methodname>. Αυτό το αναγνωριστικό μπορεί έπειτα μοιράζεται με άλλες διεργασίες έτσι ώστε οι άλλες διεργασίες να ξέρουν πώς να συνδεθούν μεταξύ τους.Μετά την προσάρτηση των γραμμών σε αυτό το πρότυπο, θα πρέπει να δώσετε το πρότυπο στην <classname>ComboBox</classname> με τη μέθοδο <methodname>set_model()</methodname>. Έπειτα χρησιμοποιήστε τις μεθόδους <methodname>pack_start()</methodname> ή <methodname>pack_end()</methodname> για να ορίσετε ποιες στήλες θα εμφανίζονται στο ComboBox. Όπως στην περίπτωση της TreeView μπορείτε είτε να χρησιμοποιήσετε την προεπιλεγμένη απόδοση κελιού περνώντας την <classname>TreeModelColumn</classname> στις μεθόδους συσκευασίας, ή μπορείτε να δημιουργήσετε μια συγκεκριμένη <classname>CellRenderer</classname> και να ορίσετε μια ειδική απεικόνιση με είτε <methodname>add_attribute()</methodname> ή <methodname>set_cell_data_func()</methodname>. Σημειώστε ότι, αυτές οι μέθοδοι είναι στη βασική κλάση <classname>CellLayout</classname>.Μετά τη δόμηση και εκτέλεση αυτού του προγράμματος, προσπαθήστε να αυξομειώσετε το παράθυρο για να δείτε τη συμπεριφορά. Επίσης, δοκιμάστε να παίξετε με τις επιλογές στη <methodname>pack_start()</methodname>, ενώ διαβάζετε την ενότητα <link linkend="sec-boxes">Πλαίσια (Boxes)</link>.Μετά τη σχεδίαση του περιγράμματος, πηγαίνουμε γύρω από το ρολόι και σχεδιάζουμε υποδιαιρέσεις για κάθε ώρα, με μια μεγαλύτερη υποδιαίρεση στα 12, 3, 6 και 9. Τώρα, τελικά είμαστε έτοιμοι να υλοποιήσουμε την λειτουργία διατήρησης του χρόνου του ρολογιού, που εμπεριέχει απλά τη λήψη των τρεχουσών τιμών για ώρες, λεπτά και δευτερόλεπτα και σχεδίαση των δεικτών στις σωστές γωνίες.Μετά την εισαγωγή του πηγαίου κώδικα στη <literal>simple.cc</literal>, μπορείτε να μεταγλωττίσετε το παραπάνω πρόγραμμα με τη <application>gcc</application> χρησιμοποιώντας: <placeholder-1/>. Σημειώστε ότι πρέπει να περιβάλετε την κλήση <literal>pkg-config</literal> με `. Τα ` προκαλούν την εκτέλεση από το φλοιό της εντολής μέσα τους και τη χρήση της εξόδου της εντολής ως μέρους της γραμμής εντολών. Σημειώστε επίσης ότι η <literal>simple.cc</literal> πρέπει να έρθει πριν την κλήση <literal>pkg-config</literal> στη γραμμή εντολών.Μετά την επιλογή του στοιχείου μενού <guimenuitem>Διάλογος πρόσφατων αρχείων</guimenuitem>, θα πρέπει να δείτε κάτι παρόμοιο με το παρακάτω παράθυρο.Μετά την ρύθμιση της σωστής ομάδας ενοτήτων, χρειάζεστε να πείτε στην <application>jhbuild</application> ποια ενότητα ή ενότητες θα δομήσετε. Για τη δόμηση της <application>gtkmm</application> και όλων των εξαρτήσεων της, ορίστε την <varname>modules</varname> ως εξής: <placeholder-1/>Μετά την έναρξη του <filename>socket</filename>, θα πρέπει να δείτε την παρακάτω έξοδο στο τερματικό:Μετά από το οποίο θα πρέπει να δείτε κάτι όπως το παρακάτω:Αφού έχετε δημιουργήσει και ρυθμίσει το φίλτρο να ταιριάζει μόνο τα στοιχεία που θέλετε, μπορείτε να εφαρμόσετε ένα φίλτρο σε ένα γραφικό συστατικό επιλογής με τη συνάρτηση <methodname>RecentChooser::add_filter()</methodname>.Αφού έχετε τελειώσει τη δημιουργία του μονοπατιού σας, δεν έχετε σχεδιάσει ακόμα τίποτα ορατό ακόμα. Για να κάνετε ορατό το μονοπάτι, πρέπει να χρησιμοποιήσετε τη συνάρτηση <methodname>stroke()</methodname> που θα βάψει το τρέχον μονοπάτι με το πλάτος της γραμμής και την τεχνοτροπία που ορίζεται στο αντικείμενό σας <classname>Cairo::Context</classname>. Μετά την πινελιά, το τρέχον μονοπάτι θα καθαριστεί έτσι ώστε να μπορείτε να ξεκινήσετε με το επόμενο μονοπάτι σας.Αφού έχετε εγκαταστήσει όλες τις εξαρτήσεις, μεταφορτώστε τον πηγαίο κώδικα της <application>gtkmm</application>, αποσυμπιέστε τον και αλλάξτε στον νεοδημιουργούμενο κατάλογο. Η <application>gtkmm</application> μπορεί να δομηθεί και να εγκατασταθεί με την ακόλουθη σειρά εντολών:Αφού έχετε εγκαταστήσει την έκδοση git της <application>gtkmm</application>, είσαστε έτοιμοι να ξεκινήσετε τη χρήση και τον πειραματισμό με αυτήν. Για να χρησιμοποιήσετε τη νέα έκδοση της <application>gtkmm</application> που μόλις εγκαταστήσατε, χρειάζεται να ορίσετε κάποιες μεταβλητές περιβάλλοντος έτσι ώστε το σενάριο <filename>configure</filename> σας να ξέρει πού θα βρει τις νέες βιβλιοθήκες. Ευτυχώς, η <application>jhbuild</application> προσφέρει μια εύκολη λύση σε αυτό το πρόβλημα. Η εκτέλεση της εντολής <command>jhbuild shell</command> θα ξεκινήσει έναν νέο φλοιό με ρυθμισμένες όλες τις σωστές μεταβλητές περιβάλλοντος. Τώρα αν ξαναρρυθμίσετε και δομήσετε το έργο σας όπως συνήθως κάνετε, πρέπει να το συνδέσετε με τις νέες εγκατεστημένες βιβλιοθήκες. Για επιστροφή στο προηγούμενό περιβάλλον σας, βγείτε απλά από τον φλοιό <application>jhbuild</application>.AhlstedtΣτοίχισηΌλα τα προγράμματα της <application>gtkmm</application> πρέπει να περιλαμβάνουν συγκεκριμένες κεφαλίδες της <application>gtkmm</application>· η <literal>gtkmm.h</literal> περιλαμβάνει το πλήρες πακέτο της <application>gtkmm</application>. Αυτό συνήθως δεν είναι καλή ιδέα, επειδή περιλαμβάνει ένα Mb περίπου κεφαλίδες, αλλά για απλά προγράμματα, επαρκεί.Όλα τα γραφικά συστατικά περιέκτη παράγονται από την <classname>Gtk::Container</classname>, όχι πάντα άμεσα. Μερικά γραφικά συστατικά περιέκτη, όπως <classname>Gtk::Grid</classname> μπορούν να κρατήσουν πολλά θυγατρικά γραφικά συστατικά, έτσι αυτά τυπικά έχουν περισσότερο σύνθετες διεπαφές. Άλλα, όπως <classname>Gtk::Frame</classname> περιέχουν μόνο ένα θυγατρικό γραφικό συστατικό.Όλες οι παρωχημένες API αφαιρέθηκαν στην <application>gtkmm</application> 3.0, αν και θα υπάρχουν νέα παρωχημένα στις μελλοντικές εκδόσεις.Όλες οι αναφορές της <varname>skeleton</varname> πρέπει να αντικατασταθούν από το σωστό όνομα της βιβλιοθήκης C που συσκευάζεται, όπως "something" ή "libsomething". Με τον ίδιο τρόπο, όλα τα στιγμιότυπα της <varname>SKELETON</varname> πρέπει να αντικατασταθούν από "SOMETHING" ή "LIBSOMETHING" και όλες οι εμφανίσεις της <varname>Skeleton</varname> να αλλαχτούν σε "Something".Επίσης, η τιμή μπορεί να σχεδιαστεί σε διαφορετικές θέσεις σχετικά με τον περιέκτη, που ορίζεται από τη μέθοδο <methodname>set_value_pos()</methodname>.Εναλλακτικά, αν μια πλήρης λίστα των πιθανών καταχωρίσεων μπορεί να είναι υπερβολικά μεγάλη ή υπερβολικά άβολη για να δημιουργηθεί, μια σχισμή επανάκλησης μπορεί να οριστεί με <methodname>set_match_func()</methodname>. Αυτό είναι επίσης χρήσιμο, αν θέλετε να ταιριάξετε ένα μέρος της συμβολοσειράς διαφορετικό από την αρχή.Εναλλακτικά, μπορείτε να επιτρέψετε ένα χειριστήριο περιέκτη του γραφικού συστατικού όταν το γραφικό συστατικό καταστρέφεται. Στις περισσότερες περιπτώσεις, θέλετε ένα γραφικό συστατικό να κρατήσει μόνο όσο ο περιέκτης είναι μέσα. Για ανάθεση της διαχείρισης χρόνου ζωής του γραφικού συστατικού στο περιέκτη του, δημιουργήστε το πρώτα με την <function>Gtk::manage()</function>και συσκευάστε το στον περιέκτη του με τις <methodname>Gtk::Container::add()</methodname>, <methodname>Gtk::Box::pack_start()</methodname>, ή μια παρόμοια μέθοδο. Τώρα, το γραφικό συστατικό θα καταστραφεί όποτε καταστρέφεται ο περιέκτης του.Αν και η <application>glib</application> είναι η ίδια με ασφάλεια νήματος, οποιοιδήποτε συσκευαστές <application>glibmm</application> που χρησιμοποιούν <application>libsigc++</application> δεν είναι. Έτσι για παράδειγμα, μόνο το νήμα στο οποίο ο κύριος βρόχος εκτελείται πρέπει να καλεί τις <methodname>Glib::SignalIdle::connect()</methodname>, <methodname>Glib::SignalIO::connect()</methodname>, <methodname>Glib::SignalTimeout::connect()</methodname>, <methodname>Glib::SignalTimeout::connect_seconds</methodname> για τον κύριο βρόχο, ή να χειρίζεται οποιοδήποτε αντικείμενο <classname>sigc::connection</classname> που επιστρέφεται από αυτές.Αν και τα στιγμιότυπα γραφικών συστατικών του <application>gtkmm</application> έχουν χρόνους ζωής και εμβέλειες ακριβώς όπως αυτά των άλλων κλάσεων της C++, η <application>gtkmm</application> έχει ένα προαιρετικό χαρακτηριστικό αποθήκευσης χρόνου που θα δείτε σε μερικά παραδείγματα. Η <function>Gtk::manage()</function> επιτρέπει να πείτε ότι ένα θυγατρικό γραφικό συστατικό κατέχεται από τον περιέκτη στον οποίο το τοποθετείτε. Αυτό σας επιτρέπει <function>new</function> γραφικό συστατικό, προσθήκη του στον περιέκτη και παράλειψη της διαγραφής του. Μπορείτε να μάθετε περισσότερα για τις τεχνικές διαχείρισης μνήμης της <application>gtkmm</application> στο <link linkend="chapter-memory">κεφάλαιο διαχείρισης μνήμης</link>.Αν και το Cairo μπορεί να αποδώσει κείμενο, δεν σημαίνει ότι είναι αντικατάσταση του Pango. Το Pango είναι μια καλύτερη επιλογή αν χρειάζεται να εκτελέσετε πιο προχωρημένη απόδοση κειμένου όπως αναδίπλωση ή ελλειπτικό κείμενο. Η σχεδίαση κειμένου με το Cairo πρέπει να γίνεται μόνο αν το κείμενο είναι μέρος ενός γραφικού.Αν και το σήμα <literal>custom_widget_apply</literal> παρέχει το γραφικό συστατικό που προηγουμένως δημιουργήσατε, για απλοποίηση των πραγμάτων μπορείτε να κρατήσετε τα γραφικά συστατικά που περιμένετε να περιέχουν κάποια είσοδο χρήστη όπως μέλη κλάσεων. Για παράδειγμα, ας πούμε ότι έχετε μια <classname>Gtk::Entry</classname> που λέγεται <literal>m_Entry</literal> ως μέλος της κλάσης σας <classname>CustomPrintOperation</classname>: <placeholder-1/>Αν και το όνομα <classname>EventBox</classname> δίνει έμφαση στη μέθοδο χειρισμού συμβάντων, το γραφικό συστατικό μπορεί επίσης να χρησιμοποιηθεί για απόκομμα (και περισσότερα· δείτε το παρακάτω παράδειγμα).Αν και έχουμε εμφανίσει την εντολή μεταγλώττισης για το απλό παράδειγμα, θα πρέπει πραγματικά να χρησιμοποιήσετε τα εργαλεία automake και autoconf, όπως περιγράφονται στο "Autoconf, Automake, Libtool", από τον G. V. Vaughan κ.α. Τα χρησιμοποιούμενα παραδείγματα σε αυτό το βιβλίο περιλαμβάνονται στο πακέτο <application>gtkmm-τεκμηρίωση</application>, με κατάλληλα αρχεία δόμησης, έτσι δεν θα εμφανίσουμε τις εντολές δόμησης στο μέλλον. Θα χρειαστείτε απλά να βρείτε τον κατάλληλο κατάλογο και να πληκτρολογήσετε <literal>make</literal>.Αν και μπορείτε να ορίσετε τη διάταξη και την εμφάνιση των παραθύρων και των γραφικών συστατικών με τον κώδικα C++, θα βρείτε πιο βολικό να σχεδιάσετε τις διεπαφές χρήστη σας με το <literal>Glade</literal> και να τις φορτώσετε στον χρόνο εκτέλεσης με <literal>Gtk::Builder</literal>. Δείτε το κεφάλαιο <link linkend="chapter-builder">Glade and Gtk::Builder</link>.Αν και μπορείτε θεωρητικά να υλοποιήσετε το δικό σας πρότυπο, θα χρησιμοποιείτε κανονικά τις κλάσεις προτύπου ή την <classname>ListStore</classname> ή την <classname>TreeStore</classname>.Αν και μπορείτε να χρησιμοποιήσετε τον κώδικα C++ για να δημιουργήσετε και να τακτοποιήσετε τα γραφικά συστατικά, αυτό μπορεί σύντομα να γίνει κουραστικό και επαναλαμβανόμενο. Και απαιτεί μια αναμεταγλώττιση για την εμφάνιση των αλλαγών. Η εφαρμογή <application>Glade</application> επιτρέπει να τακτοποιήσετε τα γραφικά συστατικά στην οθόνη και έπειτα να αποθηκεύσετε μια περιγραφή XML της διάταξης. Η εφαρμογή σας μπορεί τότε να χρησιμοποιήσει την API <application>Gtk::Builder</application> για να φορτώσει αυτό το αρχείο XML στον χρόνο εκτέλεσης και να πάρει έναν δείκτη στα ειδικά ονοματισμένα στιγμιότυπα γραφικού συστατικού.Αν και ο περιέκτης σας μπορεί να έχει τη δική του μέθοδο ορισμού των θυγατρικών γραφικών συστατικών, θα πρέπει ακόμα να δώσετε μια υλοποίηση για τις εικονικές μεθόδους <methodname>on_add()</methodname> και <methodname>on_remove()</methodname> από τη βασική κλάση, έτσι ώστε οι μέθοδοι add() και remove() να κάνουν κάτι κατάλληλο αν κληθούν.Αν και, στις περισσότερες περιπτώσεις, ο προγραμματιστής θα προτιμήσει να επιτρέψει στους περιέκτες την αυτόματη καταστροφή των θυγατρικών τους χρησιμοποιώντας την <function>Gtk::manage()</function> (δείτε παρακάτω), ο προγραμματιστής δεν απαιτείται να χρησιμοποιήσει την <function>Gtk::manage()</function>. Οι παραδοσιακοί τελεστές <literal>new</literal> και <literal>delete</literal> μπορούν επίσης να χρησιμοποιηθούν. <placeholder-1/> Εδώ, ο προγραμματιστής διαγράφει την <varname>pButton</varname> για να αποτρέψει διαρροή μνήμης.Μια <classname>Assistant</classname> χωρίζει μια σύνθετη λειτουργία σε βήματα. Κάθε βήμα είναι μια σελίδα, που περιέχει μια κεφαλίδα, ένα θυγατρικό γραφικό συστατικό και μια περιοχή ενέργειας. Η ενέργεια του βοηθού έχει πλήκτρα περιήγησης που ενημερώνουν αυτόματα ανάλογα με τον τύπο της σελίδας, που ορίστηκε με <methodname>set_page_type()</methodname>.Ένα γραφικό συστατικό <classname>Entry</classname> μπορεί να προβάλει μια γραμμή προόδου μέσα στην περιοχή κειμένου, κάτω από το εισαγόμενο κείμενο. Η γραμμή προόδου θα εμφανιστεί αν οι μέθοδοι <methodname>set_progress_fraction()</methodname> ή <methodname>set_progress_pulse_step()</methodname> κληθούν.Ένα γραφικό συστατικό <classname>Entry</classname> μπορεί να εμφανίσει ένα εικονίδιο στην αρχή ή το τέλος της περιοχής κειμένου. Το εικονίδιο μπορεί να οριστεί με μεθόδους όπως <methodname>set_icon_from_pixbuf()</methodname> ή <methodname>set_icon_from_icon_name()</methodname>. Μια εφαρμογή μπορεί να απαντά στο πάτημα του εικονιδίου από τον χρήστη με επεξεργασία του σήματος <methodname>signal_icon_press</methodname>.Μια <classname>InfoBar</classname> μπορεί να εμφανίσει μικρά στοιχεία πληροφοριών ή να ζητήσει σύντομες ερωτήσεις. Αντίθετα με έναν <classname>Dialog</classname>, εμφανίζεται στην κορυφή του τρέχοντος παραθύρου αντί για άνοιγμα ενός νέου παραθύρου. Η API της είναι πολύ παρόμοια με την API <link linkend="chapter-dialogs">Gtk::Dialog</link>.Ένα βελτιωμένο Hello WorldAnastasovΚαι εδώ είναι ένα απόσπασμα από μια συνεδρία της <application>gdb</application>. <placeholder-1/> Η εξαίρεση ελήφθη στην <application>glibmm</application> και το πρόγραμμα τελειώνει με μια κλήση στην <function>g_error()</function>. Άλλες εξαιρέσεις μπορεί να καταλήξουν σε διαφορετική συμπεριφορά, αλλά σε κάθε περίπτωση η εξαίρεση από έναν χειριστή σήματος λαμβάνεται στην <application>glibmm</application> ή την <application>gtkmm</application> και η <application>gdb</application> δεν μπορεί να δει πού συνέβη.Ένα άλλο πράγμα που πρέπει να σημειώσετε για αυτό το παράδειγμα είναι ότι κάναμε την κλήση στην <methodname>connect()</methodname> δυο φορές για το ίδιο αντικείμενο σήματος. Αυτό είναι ολότελα θαυμάσιο - όταν το πλήκτρο πατιέται, και οι δύο χειριστές σήματος θα κληθούν.Ένας άλλος τρόπος καταστροφής της σύνδεσης είναι ο χειριστής σήματός σας. Πρέπει να είναι του τύπου <classname>sigc::slot&lt;bool&gt;</classname>. Όπως βλέπετε από τον ορισμό του χειριστή σήματος πρέπει να επιστρέψει μια τιμή του τύπου <literal>bool</literal>. Ένας ορισμός μιας μεθόδου δείγματος μπορεί να δείχνει όπως αυτό: <placeholder-1/>Μια άλλη παράκαμψη είναι η προσθήκη μιας συνάρτησης <function>*_construct()</function> που ο κατασκευαστής C++ μπορεί να καλέσει μετά την αρχικοποίηση του δικού του τύπου. Για παράδειγμα, <placeholder-1/>Οποιοδήποτε αντικείμενο <classname>sigc::connection</classname> πρέπει να θεωρείται ως κατεχόμενο από το νήμα στο οποίο η μέθοδος επιστρέφει το αντικείμενο <classname>sigc::connection</classname> που κλήθηκε. Μόνο αυτό το νήμα πρέπει να καλεί τις μεθόδους <classname>sigc::connection</classname> στο αντικείμενο.Οποιαδήποτε πρόσθετα μη δημιουργούμενα πηγαία αρχεία <filename>.h</filename> και <filename>.cc</filename> μπορεί να τοποθετηθούν στο <filename>skeleton/skeletonmm/</filename> και καταχωρίζονται στο <filename>skeleton/skeletonmm/filelist.am</filename>, τυπικά στις μεταβλητές <varname>files_extra_h</varname> και <varname>files_extra_cc</varname>.Χρόνος ζωής εφαρμογήςΕφαρμογή ετικετώνΩς πρώτο βήμα για μεταφορά του πηγαίου κώδικά σας στο <application>gtkmm</application>-3.0· θα πρέπει προφανώς να εξασφαλίσετε ότι η εφαρμογή σας δομεί με την παρωχημένη <application>gtkmm</application>-2.4 με ανενεργή API, ορίζοντας μακροεντολή όπως GTK_DISABLE_DEPRECATED. Υπάρχουν μερικά αυτόματα εργαλεία μακροεντολών που μπορούν να βοηθήσουν με αυτό ορίζοντας τα προαιρετικά την ώρα δόμησης. Δείτε τη <ulink url="https://live.gnome.org/gtkmm/PortingToGtkmm3">σελίδα βίκι μεταφοράς gtkmm 3</ulink> για περισσότερες λεπτομέρειες.Όπως πριν, όλο σχεδόν το ενδιαφέρον υλικό γίνεται στον χειριστή σήματος σχεδίασης <methodname>on_draw()</methodname>. Πριν εμβαθύνουμε στον χειριστή σήματος σχεδίασης, σημειώστε ότι ο κατασκευαστής για το γραφικό συστατικό <classname>Clock</classname> συνδέει μια συνάρτηση χειριστή <methodname>on_timeout()</methodname> με ένα χρονόμετρο με μια περίοδο λήξης χρόνου των 1000 χιλιοστοδευτερολέπτων (1 δευτερολέπτου). Αυτό σημαίνει ότι η <methodname>on_timeout()</methodname> θα καλείται μια φορά ανά δευτερόλεπτο. Η μόνη ευθύνη αυτής της συνάρτησης είναι η ακύρωση του παραθύρου έτσι ώστε η <application>gtkmm</application> να εξαναγκαστεί να το ανασχεδιάσει.Όπως αναφέρθηκε παραπάνω, κάθε <classname>TextView</classname> έχει μια <classname>TextBuffer</classname> και μία ή περισσότερες <classname>TextView</classname> μπορούν να μοιραστούν την ίδια <classname>TextBuffer</classname>.Όπως αναφέρθηκε νωρίτερα, η <classname>Gtk::Adjustment</classname> μπορεί να εκπέμπει σήματα. Έτσι, φυσικά, οι ενημερώσεις γίνονται αυτόματα όταν μοιράζεστε ένα αντικείμενο <classname>Adjustment</classname> μεταξύ μιας <classname>Scrollbar</classname> και ενός άλλου προσαρμόσιμου γραφικού συστατικού· όλα τα προσαρμόσιμα γραφικά συστατικά συνδέουν χειριστές σήματος με το σήμα <literal>value_changed</literal> της προσαρμογής τους, όπως μπορεί το πρόγραμμά σας.Καθώς και μετονομασία των καταλόγων, θα πρέπει να μετονομάσουμε μερικά από τα πηγαία αρχεία. Για παράδειγμα: <placeholder-1/> Ένας αριθμός των αρχείων σκελετού πρέπει ακόμα να συμπληρωθεί με περιεχόμενο ειδικού έργου αργότερα.Όπως θα εξηγηθεί στην ενότητα <link linkend="chapter-adjustment">ρύθμιση</link>, όλα τα γραφικά συστατικά της περιοχής συσχετίζονται με ένα αντικείμενο <classname>Adjustment</classname>. Για να αλλάξετε την χαμηλότερη, ανώτερη και τρέχουσα τιμή που χρησιμοποιείται από το γραφικό συστατικό χρειάζεστε να χρησιμοποιήσετε τις μεθόδους της <classname>Adjustment</classname>, που μπορείτε να πάρετε με τη μέθοδο <methodname>get_adjustment()</methodname>. Οι προεπιλεγμένοι κατασκευαστές των γραφικών συστατικών <classname>Range</classname> δημιουργούν μια <classname>Adjustment</classname> αυτόματα, ή μπορείτε να ορίσετε μια υπάρχουσα <classname>Adjustment</classname>, μπορί να την μοιραστεί με ένα άλλο γραφικό συστατικό. Δείτε την ενότητα <link linkend="chapter-adjustment">Ρυθμίσεις</link> για παραπέρα λεπτομέρειες.Όσον αφορά <classname>Scrollbar</classname>s, ο προσανατολισμός μπορεί να είναι ή οριζόντιος ή κάθετος. Ο προεπιλεγμένος κατασκευαστής δημιουργεί μια <classname>Adjustment</classname> με όλες τις τιμές του που ορίστηκαν στο <literal>0.0</literal>. Αυτό δεν είναι χρήσιμο, έτσι θα χρειαστείτε να ορίσετε μερικές λεπτομέρειες της <classname>Adjustment</classname> για να πάρετε συμπεριφορά με νόημα.Πέρα από το γεγονός ότι συνδεμένες υποδοχές εκτελούνται πάντα στο νήμα δέκτη, τα αντικείμενα <classname>Glib::Dispatcher</classname> είναι παρόμοια με τα αντικείμενα <classname>sigc::signal&lt;void&gt;</classname>, Συνεπώς, δεν μπορούν να περάσουν αδέσμευτα ορίσματα ούτε να επιστρέψουν μια τιμή. Ο καλύτερος τρόπος να περάσουν αδέσμευτα ορίσματα είναι με ασφάλεια νήματος (ασύγχρονη) ουρά. Την ώρα της εγγραφής η <application>glibmm</application> δεν έχει κανένα, αν και οι περισσότεροι άνθρωποι που γράφουν πολυνηματικό κώδικα θα έχουν ένα διαθέσιμο για αυτούς (είναι σχετικά εύκολοι στην συγγραφή, αν και υπάρχουν λεπτές διακρίσεις στον συνδυασμό ασφάλειας νήματος με ισχυρή ασφάλεια εξαίρεσης).Σκελετός όψης (AspectFrame)ΒοηθόςΥποθέτοντας το εμφανιζόμενο μέγεθος των συμβολοσειρώνΑσύγχρονες λειτουργίεςΤην ώρα εγκατάστασης τα αρχεία <filename>.po</filename> μετατρέπονται σε δυαδική μορφή (με την επέκταση <filename>.mo</filename>) και τοποθετούνται σε ένα έναν κατάλογο όλου του συστήματος για αρχεία τοπικών ρυθμίσεων, για παράδειγμα <filename>/usr/share/locale/</filename>.Στο επίπεδο ανάπτυξης της εφαρμογής, η API εκτύπωσης της <application>gtkmm</application> παρέχει διαλόγους που είναι ομοιόμορφοι στις εφαρμογές και επιτρέπει την χρήση κοινής API σχεδίασης του Cairo, με απεικόνιση κειμένου που καθοδηγείται από το Pango. Στην υλοποίηση αυτής της κοινής API, χρησιμοποιούνται ειδικά παρασκήνια πλατφόρμας και ειδικοί οδηγοί εκτυπωτή.Τουλάχιστον, η συνάρτηση <function>_new()</function> δεν πρέπει να χρησιμοποιήσει καμία ιδιωτική API (συναρτήσεις που είναι μόνο σε αρχείο .c). Ακόμα κι αν δεν υπάρχουν συναρτήσεις, μπορούμε μερικές φορές να ξαναεφαρμόσουμε 2 ή 3 γραμμές κώδικα σε μια συνάρτηση <function>_new()</function> όσο αυτές οι γραμμές κώδικα χρησιμοποιούν API που είναι διαθέσιμη σε μας.Προς το παρόν, έχουμε ξεχωριστά εργαλεία για δημιουργία διαφορετικών τμημάτων αυτών των <filename>.defs</filename>, έτσι τα διαιρούμε σε ξεχωριστά αρχεία. Για παράδειγμα, στον κατάλογο <filename>gtk/src</filename> των πηγών <application>gtkmm</application>, θα βρείτε αυτά τα αρχεία: <placeholder-1/>Αυτόματα αποθηκευμένα επεξεργάσιμα κελιά.Ισοδύναμοι βασικοί τύποιΒασικοί τύποιΤα βασικάΕπειδή ο χρήστης μπορεί να εισάγει ένα ελεύθερο κείμενο, μια ενεργή γραμμή προτύπου δεν είναι αρκετή για να πει ποιο κείμενο έχει εισάγει ο χρήστης. Συνεπώς, θα πρέπει να ανακτήσετε το γραφικό συστατικό <classname>Entry</classname> με τη μέθοδο <methodname>ComboBox::get_entry()</methodname> και να καλέσετε <methodname>get_text()</methodname> σε αυτό.Επειδή αυτός ο αυτόματος μετασχηματισμός δεν είναι πάντα κατάλληλος, μπορεί να θελήσετε να δώσετε χειρόγραφο κείμενο για μια συγκεκριμένη μέθοδο. Μπορείτε να το κάνετε αντιγράφοντας τον κόμβο XML για τη συνάρτηση από το αρχείο σας <filename>something_docs.xml</filename> στο αρχείο <filename>something_docs_override.xml</filename> και να αλλάξετε τα περιεχόμενα.Πριν την προσπάθεια εγκατάστασης του <application>gtkmm</application> 3.0, ίσως χρειαστείτε πρώτα να εγκαταστήσετε αυτά τα άλλα πακέτα.Παρακάτω είναι ένα σύντομο παράδειγμα που επεξηγεί αυτές τις λειτουργίες. Αυτό το παράδειγμα χρησιμοποιεί το γραφικό συστατικό πλαίσιο για καλύτερη εμφάνιση των τεχνοτροπιών ετικέτας. (Το γραφικό συστατικό πλαισίου εξηγείται στην ενότητα <link linkend="sec-frame">Πλαίσιο</link>.) Είναι δυνατό ότι ο πρώτος χαρακτήρας στο <literal>m_Label_Normal</literal> εμφανίζεται υπογραμμισμένος μόνο όταν πατάτε το πλήκτρο <keycap>Alt</keycap>.BernhardΕκτός από την υπόδειξη του ποσού της προόδου που έχει συμβεί, η γραμμή προόδου μπορεί επίσης να χρησιμοποιηθεί για να δείξει ότι υπάρχει κάποια δραστηριότητα· αυτό γίνεται τοποθετώντας τη γραμμή προόδου στην <emphasis>κατάσταση δραστηριότητας</emphasis>. Σε αυτήν την κατάσταση, η γραμμή προόδου εμφανίζει ένα μικρό ορθογώνιο που μετακινείται πίσω και μπρος. Η κατάσταση δραστηριότητας είναι χρήσιμη σε περιπτώσεις, όπου η πρόοδος μιας λειτουργίας δεν μπορεί να υπολογιστεί ως μια περιοχή τιμών (π.χ., λήψη αρχείου άγνωστου μήκους).Σύνδεση πρόσθετων ορισμάτωνBjarne Stroustrup, "The C++ Programming Language" Forth Edition - section 34.3Συσκευασία πλαισίου (Box) 1Συσκευασία πλαισίου (Box) 2Πλαίσια (Boxes)Δόμηση της <application>gtkmm</application> σε Win32Αλλά αντίθετα με τους περισσότερους έξυπνους δείκτες, δεν μπορείτε να χρησιμοποιήσετε τον τελεστή * για να προσπελάσετε το υποκείμενο στιγμιότυπο.Αλλά αντίθετα με τους κανονικούς δείκτες, οι <classname>RefPtr</classname>s αρχικοποιούνται αυτόματα σε κενό, έτσι δεν χρειάζεται να θυμάστε να το κάνετε οι ίδιοι.ΚουμπίΤα πλαίσια με κουμπιά (Button boxes) είναι ένας βολικός τρόπος γρήγορης τακτοποίησης μιας ομάδας κουμπιών. Ο προσανατολισμός τους μπορεί να είναι ή οριζόντιος ή κάθετος.Τα πλαίσια με κουμπιά (Button boxes) υποστηρίζουν πολλές τεχνοτροπίες διάταξης. Η τεχνοτροπία μπορεί να ανακτηθεί και να αλλαχθεί χρησιμοποιώντας <methodname>get_layout()</methodname> και <methodname>set_layout()</methodname>.Πλαίσιο με κουμπιά (Button Box)Πλαίσια με κουμπιά (ButtonBoxes)ΚουμπιάΤα κουμπιά προστίθενται σε μία <classname>ButtonBox</classname> με τη μέθοδο <methodname>add()</methodname>.Συμβατικά, τα αντικείμενα τεχνοτροπίας glib/GTK+ έχουν συναρτήσεις <function>*_new()</function>, όπως η <function>example_widget_new()</function> που δεν κάνει τίποτα περισσότερο από το να καλεί την <function>g_object_new()</function> και να επιστρέφει το αποτέλεσμα. Οι παράμετροι εισόδου παρέχονται στη <function>g_object_new()</function> μαζί με τα ονόματα των ιδιοτήτων για τα οποία είναι τιμές. Για παράδειγμα, <placeholder-1/>Συμβατικά, οι δομές δηλώνονται σε κεφαλίδες τεχνοτροπίας glib/GTK+ ως εξής: <placeholder-1/>Από προεπιλογή, η <application>gtkmm</application> θα εγκατασταθεί στον κατάλογο <filename>/usr/local</filename>. Σε μερικά συστήματα ίσως χρειαστείτε να εγκαταστήσετε σε μια διαφορετική θέση. Για παράδειγμα, σε συστήματα Ρέντ χατ Λίνουξ μπορεί να χρησιμοποιήσετε την επιλογή <literal>--prefix</literal> με μια ρύθμιση, όπως: <screen>
# ./configure --prefix=/usr
</screen>Από προεπιλογή, η διαμόρφωση της <application>jhbuild</application> ρυθμίζεται για να εγκαταστήσει όλο το λογισμικό που δομήθηκε με την <application>jhbuild</application> κάτω από το πρόθεμα <filename>/opt/gnome</filename>. Μπορείτε να επιλέξετε ένα διαφορετικό πρόθεμα, αλλά συνιστάται να κρατήσετε αυτό το πρόθεμα διαφορετικά από άλλο λογισμικό που έχετε ήδη εγκαταστήσει (μην το ορίσετε σε <filename>/usr</filename>!) Αν έχετε ακολουθήσει τις οδηγίες jhbuild, τότε αυτό το πρόθεμα ανήκει στον χρήστη σας, έτσι δεν χρειάζεται να εκτελέσετε την jhbuild ως <literal>root</literal>.Από προεπιλογή, η <methodname>PrintOperation::run()</methodname> επιστρέφεται όταν η λειτουργία εκτύπωσης ολοκληρωθεί. Αν χρειάζεστε να εκτελέσετε μια μη ομαδική λειτουργία εκτύπωσης, καλέστε την <methodname>PrintOperation::set_allow_async()</methodname>. Σημειώστε ότι η <methodname>set_allow_async()</methodname> δεν υποστηρίζεται σε όλα τα λειτουργικά συστήματα, όμως το σήμα <literal>done</literal> θα εκπεμφθεί.Από προεπιλογή, μόνο μεμονωμένες γραμμές μπορούν να επιλεγούν, αλλά μπορείτε να επιτρέψετε πολλαπλή επιλογή ορίζοντας την κατάσταση, ως εξής: <placeholder-1/>Από προεπιλογή, οι χειριστές σήματός σας καλούνται μετά από οποιουσδήποτε προηγουμένως συνδεμένους χειριστές σήματος. Όμως, αυτό μπορεί να είναι ένα πρόβλημα με τα σήματα συμβάντος Χ. Για παράδειγμα, οι υπάρχοντες χειριστές σήματος, ή ο προεπιλεγμένος χειριστής σήματος, μπορεί να επιστρέψει <literal>true</literal> για να σταματήσει χειριστές σήματος να κληθούν. Για να ορίσετε ότι ο χειριστής σας σήματος πρέπει να κληθεί πριν τους άλλους χειριστές σήματος, έτσι ώστε να καλείται πάντα, μπορείτε να ορίσετε <literal>false</literal> για την προαιρετική παράμετρο <literal>after</literal>. Για παράδειγμα, <placeholder-1/>Παράγοντας άμεσα από την <classname>Gtk::Widget</classname> μπορείτε να κάνετε όλη τη σχεδίαση για το γραφικό συστατικό σας άμεσα, αντί μιας απλής διευθέτησης των θυγατρικών γραφικών συστατικών. Για παράδειγμα, μια <classname>Gtk::Label</classname> σχεδιάζει το κείμενο της ετικέτας, αλλά δεν το κάνει χρησιμοποιώντας άλλα γραφικά συστατικά.Αντικαθιστώντας την <methodname>forall_vfunc()</methodname> μπορείτε να επιτρέψετε στις εφαρμογές να λειτουργούν σε όλα τα θυγατρικά γραφικά συστατικά του περιέκτη. Για παράδειγμα, η <methodname>show_all_children()</methodname> χρησιμοποιεί αυτό για να βρεί όλα τα θυγατρικά γραφικά συστατικά και να τα εμφανίσει.Οι προγραμματιστές της C χρησιμοποιούν την <function>sprintf()</function> για τη σύνθεση και συνένωση συμβολοσειρών. Η C++ ευνοεί τις ροές, αλλά δυστυχώς, αυτή η προσέγγιση κάνει δύσκολη τη μετάφραση, επειδή κάθε τμήμα κειμένου μεταφράζεται ξεχωριστά, χωρίς να επιτρέπει στους μεταφραστές να τις αναδιατάξουν σύμφωνα με τη γραμματική της γλώσσας.Τύπος CΤύπος C++Cairo και PangoΚαλέστε τη <methodname>add_drag_dest()</methodname> για να επιτρέψετε σε στοιχεία ή ομάδες να μετακινηθούν από την παλέτα εργαλείων σε έναν συγκεκριμένο γραφικό συστατικό προορισμού. Μπορείτε έπειτα να χρησιμοποιήσετε την <methodname>get_drag_item()</methodname> για να βρείτε ποιο ToolItem ή ToolItemGroup μεταφέρθηκε. Μπορείτε να χρησιμοποιήσετε την <literal>dynamic_cast</literal> για να βρείτε αν είναι ένα στοιχείο ή μια ομάδα. Για παράδειγμα, μπορεί να χρησιμοποιήσετε αυτό στον χειριστή σήματός σας <literal>drag_data_received</literal>, για να προσθέσετε ένα αποτιθέμενο στοιχείο, ή να εμφανίσετε ένα κατάλληλο εικονίδιο κατά τη μεταφορά.Καλέστε <methodname>show()</methodname> για να εμφανίσετε το γραφικό συστατικό.Αλλαγή τύπουΚελιά σε μια <classname>TreeView</classname> μπορούν να επεξεργαστούν επί τόπου από τον χρήστη. Για να το επιτρέψετε αυτό, χρησιμοποιήστε τις μεθόδους <classname>Gtk::TreeView</classname><methodname>insert_column_editable()</methodname> και <methodname>append_column_editable()</methodname> αντί για <methodname>insert_column()</methodname> και <methodname>append_column()</methodname>. Όταν αυτά τα κελιά επεξεργάζονται τις νέες τιμές θα αποθηκεύονται άμεσα στο πρότυπο. Σημειώστε ότι αυτές οι μέθοδοι είναι πρότυπα που μπορούν μόνο να δημιουργηθούν για απλούς τύπους στήλης όπως <classname>Glib::ustring</classname>, ακέραιο και μεγάλο αριθμό.Αλλαγές στη <application>gtkmm</application> 3Η αλλαγή της διάταξης ενός παραθύρου "άμεσα", για να εμφανιστούν κάποια πρόσθετα γραφικά συστατικά, για παράδειγμα, είναι σύνθετη. Απαιτεί κουραστικούς επανυπολογισμούς κάθε θέσης του γραφικού συστατικού.Αλλαγή της επιλογήςΚεφάλαιο "Σχεδίαση με Cairo".Κεφάλαιο "Πολυνηματικά προγράμματα".Κεφάλαιο "Εκτύπωση".Κεφάλαιο "Πρόσφατα αρχεία".Κεφάλαιο "Όρια χρόνου".Κεφάλαιο "Εργασία με πηγαίο κώδικα του gtkmm".Κεφάλαιο στα συμβάντα πληκτρολογίου.Κουμπί ελέγχουΠλαίσια ελέγχουΈλεγχος για κενόΤα θυγατρικά γραφικά συστατικά μπορούν να καλύψουν πολλαπλές γραμμές ή στήλες, χρησιμοποιώντας την <methodname>attach()</methodname>, ή να προστεθούν δίπλα σε ένα υπάρχον γραφικό συστατικό μέσα στο πλέγμα με την <methodname>attach_next_to()</methodname>. Μεμονωμένες γραμμές και στήλες του πλέγματος μπορούν να οριστούν ώστε να έχουν ομοιόμορφο ύψος ή πλάτος με τις <methodname>set_row_homogeneous()</methodname> και <methodname>set_column_homogeneous()</methodname>.ChrisΤα γραφικά συστατικά εμβέλειας κλάσηςΜακροεντολές κλάσηςΠρόχειρο - ΙδανικόΠρόχειρο - ΑπλόΔιάλογος επιλογής χρώματος (ColorChooserDialog)Σύνθετα πλαίσιαComboBoxComboBox με καταχώρισηComboBox με μια καταχώρισηComboBoxTextComboBoxText με καταχώρισηΣύγκριση με άλλα συστήματα σηματοδότησηςΣύνθεση των συμβολοσειρώνΣυνδέστε οποιοδήποτε σήμα που θέλετε να χρησιμοποιήσετε με τους κατάλληλους χειριστές.Σύνδεση δοτών και δεκτώνΣύνδεση χειριστών σημάτωνΑντικείμενα σταθερών χρησιμοποιούνται μέσα από <classname>RefPtr</classname>: Αν το αντικείμενο δεν πρέπει να αλλαχθεί από τη συνάρτηση, τότε διασφαλίστε ότι το αντικείμενο είναι σταθερά, ακόμα κι αν η <classname>RefPtr</classname> είναι ήδη σταθερά. Για παράδειγμα, η <code>const Glib::RefPtr&lt;const Gtk::FileFilter&gt;&amp; filter</code>.ΣταθερότηταΜακροεντολές κατασκευαστήΚατασκευαστέςΓραφικά συστατικά περιέκτηΑντίθετα με άλλα συμβάντα, τα συμβάντα πληκτρολογίου στέλνονται πρώτα στο παράθυρο ανωτάτου επιπέδου (<classname>Gtk::Window</classname>), όπου θα ελεγχθεί για οποιεσδήποτε συντομεύσεις πληκτρολογίου που μπορούν να οριστούν (πλήκτρα επιταχυντή και μνημονικά, που χρησιμοποιούνται για επιλογή στοιχείων μενού από το πληκτρολόγιο). Μετά από αυτό (και θεωρώντας ότι το συμβάν δεν επεξεργάστηκε), στέλνεται στο γραφικό συστατικό που έχει την εστίαση και η διάδοση ξεκινά από εκεί.ΣυνεισφοράΑντιγραφήΑντιγραφήΑντιγραφή του έργου σκελετούΔημιουργήστε μια <classname>Plug</classname> ανεξάρτητα από οποιαδήποτε συγκεκριμένη <classname>Socket</classname> και περάστε το αναγνωριστικό της <classname>Plug</classname> σε άλλες διεργασίες που χρειάζονται να την χρησιμοποιήσουν. Το αναγνωριστικό της <classname>Plug</classname> μπορεί να συσχετιστεί με ένα συγκεκριμένο αντικείμενο <classname>Socket</classname> χρησιμοποιώντας τη συνάρτηση <methodname>Socket::add_id()</methodname>. Αυτή είναι η χρησιμοποιούμενη προσέγγιση στο παρακάτω παράδειγμα.Δημιουργήστε ένα αντικείμενο <classname>Socket</classname> σε μια διεργασία και περάστε το αναγνωριστικό της <classname>Socket</classname> σε μια άλλη διεργασία έτσι ώστε να μπορεί να δημιουργήσει ένα αντικείμενο <classname>Plug</classname> ορίζοντας το δοσμένο αναγνωριστικό της <classname>Socket</classname> στον κατασκευαστή της. Δεν υπάρχει τρόπος εκχώρησης μιας <classname>Plug</classname> σε μια ειδική <classname>Socket</classname> μετά τη δημιουργία, έτσι πρέπει να περάσετε το αναγνωριστικό <classname>Socket</classname> στον κατασκευαστή της <classname>Plug</classname>.Δημιουργήστε έναν υποκατάλογο με όνομα <literal>po</literal> στον ριζικό κατάλογο του έργου σας. Αυτός ο κατάλογος θα περιέχει τελικά όλες τις μεταφράσεις σας. Μέσα σε αυτόν, δημιουργήστε ένα αρχείο με όνομα <literal>LINGUAS</literal> και ένα αρχείο με όνομα <literal>POTFILES.in</literal>. Είναι κοινή πρακτική να δημιουργείτε επίσης ένα αρχείο <literal>ChangeLog</literal> στον κατάλογο <literal>po</literal>, έτσι ώστε οι μεταφραστές να μπορούν να παρακολουθούν τις αλλαγές της μετάφρασης.Δημιουργήστε τα δικά σας σήματα αντί να περάσετε ολόγυρα δείκτες. Τα αντικείμενα μπορούν να επικοινωνούν μεταξύ τους μέσα από σήματα και χειριστές σήματος. Αυτό είναι πολύ πιο απλό από αντικείμενα που κρατούν δείκτες μεταξύ τους και καλούν μεθόδους μεταξύ τους. Οι κλάσεις <application>gtkmm</application> χρησιμοποιούν ειδικές εκδόσεις της <classname>sigc::signal</classname>, αλλά θα πρέπει να χρησιμοποιήσετε κανονικά <classname>sigc::signal</classname>s, όπως περιγράφεται στην τεκμηρίωση <application>libsigc++</application>.Δημιουργία αρχείων .hg και .ccgΔημιουργία μιας προσαρμογήςΔημιουργία των σημάτων σας.CummingΠρος το παρόν, η <application>gettext</application> δεν υποστηρίζει χαρακτήρες μη ASCII (δηλαδή οποιονδήποτε χαρακτήρα με κωδικό πάνω από 127) στον πηγαίο κώδικα. Για παράδειγμα, δεν μπορείτε να χρησιμοποιήσετε το σύμβολο πνευματικών δικαιωμάτων (©).Προσαρμοσμένος περιέκτηςΠροσαρμοσμένοι περιέκτεςΠροσαρμοσμένο γραφικό συστατικόΠροσαρμοσμένα γραφικά συστατικάDISTCLEANFILES = ... intltool-extract \
                 intltool-merge \
                 intltool-update \
                 po/.intltool-merge-cacheDanielDavidΔηλώστε μια μεταβλητή του τύπου <classname>Widget</classname> που θέλετε να χρησιμοποιήσετε, γενικά ως μεταβλητή μέλους μιας παραγόμενης κλάσης περιέκτη. Μπορείτε επίσης να δηλώσετε έναν δείκτη στον τύπο γραφικού συστατικού και έπειτα να τον δημιουργήστε με <literal>new</literal> στον κώδικά σας. Ακόμα κι όταν χρησιμοποιείτε το γραφικό συστατικό μέσα από έναν δείκτη, είναι ακόμα προφανώς βέλτιστο να κάνετε αυτόν τον δείκτη μια μεταβλητή μέλους της κλάσης περιέκτη έτσι ώστε να μπορείτε να την προσπελάσετε αργότερα.Προεπιλεγμένη μορφοποίησηΟρίστε το <literal>INTLTOOL_FILES</literal> ως: <placeholder-1/>Ορίζει έναν προσαρμοσμένο προορισμό προχείρου, αν και η μορφή αυτού του προορισμού είναι ακόμα κείμενο.ΕξαρτήσειςΑποαναφοράΟι σχεδιαστές χωρίς προγραμματιστικές δεξιότητες μπορούν να δημιουργήσουν και να επεξεργαστούν διεπαφές χρήστη.ΔιάλογοιΟι διάλογοι χρησιμοποιούνται ως δευτερεύοντα παράθυρα, για να δώσουν ειδικές πληροφορίες ή να ρωτήσουν. Τα παράθυρα <classname>Gtk::Dialog</classname> περιέχουν λίγα προσυσκευασμένα γραφικά συστατικά για να εξασφαλίσουν σταθερότητα και μια μέθοδο <methodname>run()</methodname> που φράσσει μέχρι ο χρήστης να διώξει τον διάλογο.Διαφορετικές εφαρμογές περιέχουν διαφορετικούς τύπους δεδομένων και μπορεί να κάνουν τα δεδομένα διαθέσιμα σε μια ποικιλία μορφών. Η <application>gtkmm</application> καλεί αυτούς τους τύπους δεδομένων <literal>target</literal>s.Διαφορετικοί τύποι ένωσης στο CairoΑποσύνδεση χειριστών σημάτωνΕύρεση των διαθέσιμων προορισμώνΚάντε μια πρόσθετη <function>reference()</function> στην τιμής επιστροφής μιας υποκατεστημένης συνάρτησης <function>something_vfunc()</function> στη συνάρτηση επανάκλησης C, στην περίπτωση της συνάρτησης κλήσης C περιμένει να δώσει μια αναφορά.Κάντε μια πρόσθετη <function>reference()</function> στην τιμή επιστροφής της εικονικής μεθόδου <function>on_something()</function>, στην περίπτωση που η συνάρτηση C δεν παρέχει μια αναφορά.Κάντε μια πρόσθετη <function>reference()</function> στην τιμή επιστροφής της συνάρτησης <function>something_vfunc()</function>, στην περίπτωση που η εικονική συνάρτηση C δεν παρέχει αναφορά.Κάντε μια πρόσθετη <function>reference()</function> στην τιμής επιστροφής, σε περίπτωση που η συνάρτηση C δεν δίνει αναφορά.Μην δημιουργείτε μια συνάρτηση επανάκλησης C για το σήμα. Χρησιμοποιήστε αυτό όταν πρέπει να δημιουργήσετε μια συνάρτηση επανάκλησης με το χέρι.Μην δημιουργείτε μια συνάρτηση επανάκλησης C για την vfunc. Χρησιμοποιήστε αυτό όταν πρέπει να δημιουργήσετε μια συνάρτηση επανάκλησης με το χέρι.Μην δημιουργείτε έναν ορισμό της εικονικής συνάρτησης στο αρχείο <filename>.cc</filename>. Χρησιμοποιήστε αυτό όταν πρέπει να δημιουργήσετε την εικονική συνάρτηση με το χέρι.Μην δημιουργείτε μια εικονική μέθοδο <function>on_something()</function> για να επιτρέψετε την εύκολη αντικατάσταση του προεπιλεγμένου χειριστή σήματος. Η χρήση του κατά την προσθήκη ενός σήματος με προεπιλεγμένο χειριστή σήματος μπορεί να σπάσει το ABI αυξάνοντας το μέγεθος του πίνακα εικονικής συνάρτησης της κλάσης.ΤεκμηρίωσηΔιάρθρωση κατασκευής τεκμηρίωσηςΜεταφορά κι απόθεσηΠεριεχόμενο μεταφοράς (DragContext)Σχεδίαση τόξων και κύκλωνΠεριοχή σχεδίασης - ΤόξαΠεριοχή σχεδίασης - ΕικόναΠεριοχή σχεδίασης - ΓραμμέςΠεριοχή σχεδίασης - ΚείμενοΠεριοχή σχεδίασης - Λεπτές γραμμέςΣχεδίαση καμπύλων γραμμώνΣχεδίαση εικόνωνΣχεδίαση ευθειών γραμμώνΣχεδίαση κειμένουΣχεδίαση κειμένου με PangoΣχεδίαση αριστερόστροφαΣχεδίαση λεπτών γραμμώνΣχεδίαση με σχετικές συντεταγμένεςΚατά τη διάρκεια μιας <literal>move</literal>, το πηγαίο γραφικό συστατικό θα εκπέμψει επίσης αυτό το σήμα: <placeholder-1/>Δυναμική κατανομή με manage() και add()Η δυναμική κατανομή με νέο και διαγραφήΚάθε <classname>Cairo::Context</classname> συσχετίζεται με μια ειδική <classname>Gdk::Window</classname>, έτσι ώστε η πρώτη γραμμή του παραπάνω παραδείγματος να δημιουργεί ένα γραφικό συστατικό <classname>Gtk::DrawingArea</classname> και η δεύτερη γραμμή να χρησιμοποιεί την συνδεμένη <classname>Gdk::Window</classname> για να δημιουργήσει ένα αντικείμενο <classname>Cairo::Context</classname>. Οι τελικές δύο γραμμές αλλάζουν την κατάσταση γραφικών του περιεχομένου.Κάθε <classname>Gtk::TextBuffer</classname> χρησιμοποιεί μια <classname>Gtk::TextBuffer::TagTable</classname>, που περιέχει τις <classname>Tag</classname>s για αυτή την ενδιάμεση μνήμη. 2 ή περισσότερες <classname>TextBuffer</classname>s μοιράζονται την ίδια <classname>TagTable</classname>. Όταν δημιουργείτε <classname>Tag</classname>s θα πρέπει να τις προσθέσετε στη <classname>TagTable</classname>. Για παράδειγμα:Κάθε <classname>Gtk::TreeView</classname> έχει μια συνδεμένη <classname>Gtk::TreeModel</classname>, που περιέχει τα εμφανιζόμενα δεδομένα από την <classname>TreeView</classname>. Κάθε <classname>Gtk::TreeModel</classname> μπορεί να χρησιμοποιηθεί από περισσότερες από μία <classname>Gtk::TreeView</classname>. Για παράδειγμα, αυτό επιτρέπει τα ίδια υποκείμενα δεδομένα να εμφανίζονται και να επεξεργάζονται με 2 διαφορετικούς τρόπους ταυτόχρονα. Ή οι 2 προβολές μπορεί να εμφανίζουν διαφορετικές στήλες από τα ίδια δεδομένα του προτύπου, κατά τον ίδιο τρόπο που 2 ερωτήματα SQL (ή "προβολές") μπορείνα εμφανίζουν διαφορετικά πεδία από τον ίδιο πίνακα βάσης δεδομένων.Κάθε στοιχείο στον κατάλογο των πρόσφατα χρησιμοποιημένων αρχείων ταυτοποιείται από το URI του και μπορεί να συσχετιστεί με μεταδεδομένα. Τα μεταδεδομένα μπορούν να χρησιμοποιηθούν για τον ορισμό του τρόπου εμφάνισης του αρχείου, μια περιγραφή του αρχείου, τον τύπο του mime, ποια εφαρμογή το καταχωρίζει, αν είναι ιδιωτικό στην εφαρμογή καταχώρισης και πολλά άλλα πράγματα.Κάθε γραμμή περιέχει ένα οριζόντιο <classname>Box</classname> με αρκετά κουμπιά. Κάθε κουμπί σε μια γραμμή συσκευάζεται σε ένα <classname>Box</classname> με τα ίδια ορίσματα στη μέθοδο <methodname>pack_start()</methodname>.Επεξεργάσιμα κελιάElstnerΕκπέμπεται όταν πατιέται το κουμπί και ελευθερώνεται.Εκπέμπεται όταν πατιέται το κουμπί.Εκπέμπεται όταν πατιέται το κουμπί.Εκπέμπεται όταν ο δείκτης του ποντικιού αφήνει το παράθυρο του κουμπιού.Εκπέμπεται όταν ο δείκτης του ποντικιού μετακινείται πάνω από το παράθυρο του κουμπιού.ΚαταχώρισηΣυμπλήρωση καταχώρισηςΠαράδειγμα συμπλήρωσης καταχώρισηςΠαράδειγμα εικονιδίου καταχώρισηςΕικονίδια καταχώρισηςΠρόοδος καταχώρισηςΠαράδειγμα προόδου καταχώρισηςΤα γραφικά συστατικά καταχώρισης επιτρέπουν στον χρήστη να εισάγει κείμενο. Μπορείτε να αλλάξετε τα περιεχόμενα με τη μέθοδο <methodname>set_text()</methodname> και να διαβάσετε τα τρέχοντα περιεχόμενα με τη μέθοδο <methodname>get_text()</methodname>.Καταχώριση με εικονίδιοΚαταχώριση με γραμμή προόδουΑπαριθμήσεις.Διάδοση συμβάντοςΔιάδοση συμβάντος σημαίνει ότι, όταν ένα συμβάν εκπέμπεται σε ένα συγκεκριμένο γραφικό συστατικό, μπορεί να περαστεί στο γονικό τους γραφικό συστατικό (και αυτό το γραφικό συστατικό μπορεί να το περάσει στο γονικό του, και ούτω καθεξής) και, αν το γονικό έχει έναν χειριστή συμβάντος, αυτός ο χειριστής θα κληθεί.Πλαίσιο συμβάντων (Event Box)ΠαράδειγμαΕφαρμογή παραδείγματος: Δημιουργία ενός ρολογιού με CairoΠαραδείγματαΕξαιρέσεις στους χειριστές σήματοςΑναμένεται UTF8Εξαγωγή σε PDFΕπέκταση του διαλόγου εκτύπωσηςFerreiraΕπιλογέας αρχείου (FileChooser)Διάλογος επιλογής αρχείου (FileChooserDialog)Φιλτράρισμα πρόσφατων αρχείωνΤελικά, ελέγξτε την κατάσταση. Για παράδειγμα, <placeholder-1/>Τελικά, για να σας επιτρέψει το πρόγραμμα να χρησιμοποιήσετε τη μετάφραση για την τρέχουσα τοπική ρύθμιση, προσθέστε αυτόν τον κώδικα στην αρχή του αρχείου <filename>main.cc</filename>, για την αρχικοποίηση του gettext. <placeholder-1/>Δημιουργήστε πρώτα τις <classname>Action</classname>s και προσθέστε τες σε μια <classname>ActionGroup</classname>, με την <methodname>ActionGroup::add()</methodname>.Πρώτα, δημιουργούμε ένα αποθηκευμένο αντικείμενο στον έξυπνο δείκτη <classname>RefPtr</classname> που λέγεται <literal>app</literal>. Αυτό είναι του τύπου <classname>Gtk::Application</classname>. Κάθε πρόγραμμα της <application>gtkmm</application> πρέπει να έχει ένα από αυτά. Περνάμε τα ορίσματα της γραμμής εντολών μας στη μέθοδο της create(). Παίρνει τα ορίσματα που θέλει και σας αφήνει τα υπόλοιπα, όπως περιγράψαμε νωρίτερα.Πρώτα, ας κοιτάξουμε ένα απλό παράδειγμα όπου μια εξαίρεση προκαλείται από μια κανονική συνάρτηση (χωρίς χειριστή σήματος). <placeholder-1/>Διάλογος επιλογής γραμματοσειράς (FontChooserDialog)Για ένα CellRendererToggle, μπορείτε να ορίσετε την <emphasis>ενεργοποιήσιμη</emphasis> ιδιότητα στη θέση του.Για όλες τις μακροεντολές που επεξεργάζονται υπογραφές μεθόδου εκτός από τις <function>_WRAP_SIGNAL()</function> και <function>_WRAP_VFUNC()</function> είναι επίσης δυνατό να κάνουν τις παραμέτρους προαιρετικές, έτσι ώστε οι πρόσθετες μέθοδοι C++ να δημιουργηθούν χωρίς την καθορισμένη προαιρετική παράμετρο. Για παράδειγμα, ας πούμε ότι η παρακάτω συνάρτηση <function>*_new()</function> συσκευάστηκε ως κατασκευαστής στην κλάση <classname>Gtk::ToolButton</classname>: <placeholder-1/> Επίσης, ας πούμε ότι η API της C επέτρεψε NULL για την παράμετρο <parameter>label</parameter> της συνάρτησης, έτσι ώστε αυτή η παράμετρος να είναι προαιρετική. Θα ήταν πιθανό να κάνετε την <command>gmmproc</command> να δημιουργήσει τον αρχικό κατασκευαστή (με όλες τις παραμέτρους) μαζί με έναν πρόσθετο κατασκευαστή χωρίς αυτήν την προαιρετική παράμετρο προσαρτώντας ένα <literal>{?}</literal> στο όνομα παραμέτρου ως εξής: <placeholder-2/> Σε αυτήν την περίπτωση, δύο κατασκευαστές μπορεί να δημιουργηθούν: Ένας με την προαιρετική παράμετρο και ένας χωρίς αυτήν.Για όλες τις μακροεντολές που επεξεργάζονται υπογραφές μεθόδου, είναι δυνατό να ορίσετε μια διαφορετική σειρά για τις παραμέτρους C++ αντί για την υπάρχουσα σειρά στη συνάρτηση C, στην εικονική συνάρτηση ή σήμα. Για παράδειγμα, ας πούμε ότι η παρακάτω συνάρτηση C συσκευάστηκε ως μια μέθοδος C++ για την κλάση <classname>Gtk::Widget</classname>: <placeholder-1/> Όμως, η αλλαγή της σειράς των δύο παραμέτρων της μεθόδου C++ είναι απαραίτητη. Κάτι όπως το επόμενο μπορεί να συσκευάσει την συνάρτηση ως μια μέθοδο C++ με διαφορετική σειρά για τις δύο παραμέτρους: <placeholder-2/> Η <literal>{c_param_name}</literal> ακολουθώντας τα ονόματα παραμέτρου μεθόδου λέει στη <command>gmmproc</command> να απεικονίσει την παράμετρο C++ στην καθορισμένη παράμετρο C μέσα στην <literal>{}</literal>. Αφού τα ονόματα παραμέτρου της C++ αντιστοιχούν σε αυτά της C, το παραπάνω μπορεί να ξαναγραφτεί ως: <placeholder-3/>Για οποιαδήποτε κλάση <classname>RecentChooser</classname>, αν δεν θέλετε να εμφανίσετε όλα τα στοιχεία στον κατάλογο των πρόσφατων αρχείων, μπορείτε να φιλτράρετε τον κατάλογο για να εμφανίσετε μόνο αυτά που θέλετε. Μπορείτε να φιλτράρετε τον κατάλογο με τη βοήθεια της κλάσης <classname>RecentFilter</classname>. Αυτή η κλάση επιτρέπει το φιλτράρισμα πρόσφατων αρχείων με το όνομά τους (<methodname>add_pattern()</methodname>), τον mime τύπο τους, (<methodname>add_mime_type()</methodname>), την εφαρμογή που τις καταχωρίζει (<methodname>add_application()</methodname>), ή με μια συνάρτηση προσαρμοσμένου φίλτρου (<methodname>add_custom()</methodname>). Παρέχει επίσης τη δυνατότητα φιλτραρίσματος με βάση τον χρόνο τροποποίησης και τις ομάδες που ανήκει.Για κάθε σελίδα που χρειάζεται να απεικονιστεί, τα παρακάτω σήματα εκπέμπονται: <placeholder-1/>Για παράδειγμα, για <classname>Pango::Analysis</classname> in <filename>item.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>icontheme.hg</filename>: <placeholder-1/>Για παράδειγμα, αν υπήρξε μια συνάρτηση C που επέστρεψε έναν <type>GtkWidget*</type> και για κάποιον λόγο, αντί να έχει τη μέθοδο C++ επέστρεψε επίσης το γραφικό συστατικό και ήταν επιθυμητό να έχει τοποθετήσει στη μέθοδο C++ το γραφικό συστατικό σε μια συγκεκριμένη παράμετρο εξόδου, μια μακροεντολή αρχικοποίησης όπως η ακόλουθη μπορεί να είναι απαραίτητη: <placeholder-1/>Για παράδειγμα, στο <filename>rectangle.hg</filename>: <placeholder-1/>Για παράδειγμα, σε Pangomm, <filename>layoutline.hg</filename>: <placeholder-1/>Για πληροφορίες υλοποίησης των δικών σας σημάτων αντί για απλή σύνδεση σε υπάρχοντα σήματα της <application>gtkmm</application>, δείτε το <link linkend="chapter-custom-signals">παράρτημα</link>.Για παράδειγμα,Για παράδειγμα, η <application>gedit</application> μπορεί να παρέχει και να δέχεται τον προορισμό <literal>"UTF8_STRING"</literal>, έτσι μπορείτε να επικολλήσετε δεδομένα στην <application>gedit</application> από οποιαδήποτε εφαρμογή που δίνει αυτόν τον προορισμό. Ή δύο διαφορετικές εφαρμογές επεξεργασίας εικόνας μπορεί να παρέχουν και να δέχονται μια ποικιλία μορφών εικόνας ως προορισμούς. Όσο μια εφαρμογή μπορεί να δεχτεί έναν από τους προορισμούς που η άλλη παρέχει, τόσο θα μπορείτε να αντιγράψετε δεδομένα από την μία στην άλλη.Για παράδειγμα, <placeholder-1/>Για παράδειγμα, για <classname>Gdk::Rectangle</classname>: <placeholder-1/>Για παράδειγμα, για <classname>Pango::AttrIter</classname>: <placeholder-1/>Για παράδειγμα, για <classname>Pango::Coverage</classname>: <placeholder-1/>Για παράδειγμα, για CellRendererText, μπορείτε να ορίσετε την ιδιότητα <emphasis>επεξεργάσιμο</emphasis> του κελιού σε αληθές, ως εξής:Για παράδειγμα, από <classname>Gdk::RGBA</classname>: <placeholder-1/>Για παράδειγμα, από <classname>Glib::Checksum</classname>: <placeholder-1/>Για παράδειγμα, από το <filename>accelgroup.hg</filename>: <placeholder-1/>Για παράδειγμα, από το <filename>button.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>buttonbox.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>celleditable.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>container.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>entry.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>enums.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>pixbuf.hg</filename>: <placeholder-1/>Για παράδειγμα, από <filename>widget.hg</filename>: <placeholder-1/>Για παράδειγμα, ας θεωρήσουμε ότι πακετάρουμε μια βιβλιοθήκη C που λέγεται libsomething. Παρέχει μια API με βάση <classname>GObject</classname> με επώνυμους τύπους, για παράδειγμα, <classname>SomeWidget</classname> και <classname>SomeStuff</classname>.Για παράδειγμα, αυτός ο κώδικας μπορεί να είναι προβληματικός:Για παράδειγμα, για τη δημιουργία ενός σήματος που στέλνει 2 παραμέτρους, έναν <type>bool</type> και έναν <type>int</type>, δηλώστε απλά μια <classname>sigc::signal</classname>, ως εξής: <placeholder-1/>Για παράδειγμα:Για περισσότερο λεπτομερείς πληροφορίες για τα σήματα, δείτε το <link linkend="chapter-signals">παράρτημα</link>.Για πολλαπλή επιλογή, χρειάζεται να ορίσετε μια επανάκληση και να της δώσετε <methodname>selected_foreach()</methodname>, <methodname>selected_foreach_path()</methodname>, ή <methodname>selected_foreach_iter()</methodname>, ως εξής:Για αναφορά, είναι δυνατή η δημιουργία ενός αρχείου που περιέχει όλες τις συμβολοσειρές που εμφανίζονται στον κώδικά σας, ακόμα κι αν δεν σημειώνονται για μετάφραση, μαζί με το όνομα του αρχείου και τις αναφορές αριθμού γραμμής. Για τη δημιουργία ενός τέτοιου αρχείου με όνομα <literal>my-strings</literal>, εκτελέστε την ακόλουθη εντολή, μέσα στον κατάλογο του πηγαίου κώδικα: <placeholder-1/>Για μεμονωμένη επιλογή, μπορείτε να καλέσετε απλά την <methodname>get_selected()</methodname>, ως εξής:Για την είσοδο των κωδικών πρόσβασης, συνθηματικών και άλλων πληροφοριών που δεν θέλετε να εμφανίζονται στην οθόνη, η κλήση της <methodname>set_visibility()</methodname> με <literal>false</literal> θα προκαλέσει την απόκρυψη του κειμένου.Σκελετός (frame)Οι σκελετοί (Frames) μπορούν να περικλείουν ένα ή μια ομάδα γραφικών συστατικών μέσα σε ένα πλαίσιο, προαιρετικά με τίτλο. Για παράδειγμα, μπορείτε να βάλετε μια ομάδα <classname>RadioButton</classname>s ή <classname>CheckButton</classname>s σε μια <classname>Frame</classname>.Κάπου-κάπου, μπορεί να είναι χρήσιμο να μπορείτε να ενσωματώσετε ένα γραφικό συστατικό από μια άλλη εφαρμογή στην εφαρμογή σας. Η <application>gtkmm</application> επιτρέπει να το κάνετε αυτό με τις κλάσεις <classname>Gtk::Socket</classname> και <classname>Gtk::Plug</classname>. Δεν είναι αναμενόμενο ότι πάρα πολλές εφαρμογές θα χρειαστούν αυτήν τη λειτουργία, αλλά στην σπάνια περίπτωση που χρειαστείτε να εμφανίσετε ένα γραφικό συστατικό που εκτελείται σε μια ολότελα διαφορετική επεξεργασία, αυτές οι κλάσεις μπορεί να είναι πολύ χρήσιμες.Πλήρες παράδειγμαΓραφικά συστατικά εμβέλειας συνάρτησηςGTK+ 3.0Οι GTK+ και <application>gtkmm</application> σχεδιάστηκαν να δουλεύουν καλά με τα Microsoft Windows και οι προγραμματιστές ενθαρρύνουν τη χρήση τους σε λειτουργικό win32. Όμως, τα Windows δεν έχουν τυπικό σύστημα εγκατάστασης για ανάπτυξη βιβλιοθηκών. Παρακαλούμε, δείτε τη σελίδα <ulink url="http://live.gnome.org/gtkmm/MSWindows">Εγκατάσταση Windows</ulink> για οδηγίες και σημειώσεις εγκατάστασης ειδικής για Windows.Η GTK+ χρησιμοποιεί την API σχεδίασης <ulink url="http://cairographics.org">Cairo</ulink>. Με την <application>gtkmm</application>, μπορείτε να χρησιμοποιήσετε την API της C++ για cairo <ulink url="http://www.cairographics.org/cairomm/">cairomm</ulink>.Δημιουργήστε μια δήλωση της εικονικής μεθόδου <function>on_something()</function> στο αρχείο <filename>.h</filename>, αλλά μην δημιουργήσετε έναν ορισμό στο αρχείο <filename>.cc</filename>. Χρησιμοποιήστε το όταν πρέπει να δημιουργήσετε τον ορισμό με το χέρι.Δημιουργία των αρχείων .defs.Δημιουργία των απαριθμήσεων .defsΔημιουργία των μεθόδων .defsΔημιουργώντας τα σήματα και τις ιδιότητες .defsΗ παραγωγή του πηγαίου κώδικα για μια API συσκευαστή τεχνοτροπίας gtkmm απαιτεί τη χρήση εργαλείων όπως <command>gmmproc</command> και <filename>generate_wrap_init.pl</filename>. Θεωρητικά, μπορείτε να γράψετε τα δικά σας αρχεία δόμησης για να χρησιμοποιήσετε κατάλληλα, αλλά μια πολύ καλύτερη επιλογή είναι να χρησιμοποιήσετε την παρεχόμενη υποδομή δημιουργίας από την ενότητα mm-common. Για να ξεκινήσετε, βοηθά πολύ η επιλογή υπαρχουσών ενοτήτων σύνδεσης ως ένα παράδειγμα για να δείτε.Λήψη των δεδομένων από τα γραφικά συστατικά στον χειριστή σήματος <literal>custom_widget_apply</literal>.Λήψη βοήθειας με τις μεταφράσειςΛήψη τιμώνΔώστε όλες τις επιλογές της γραμμής εντολών στη <methodname>Gtk::Application::create()</methodname> και προσθέστε τη σημαία <literal>Gio::APPLICATION_HANDLES_COMMAND_LINE</literal>. Συνδέστε έναν χειριστή σήματος στο σήμα <literal>command_line</literal> και χειριστείτε τις επιλογές της γραμμής εντολών στον χειριστή σήματος.Glade and Gtk::BuilderGlib::IO_ERR - Κλήση της μεθόδου σας όταν ένα σφάλμα προκύψει στον περιγραφέα αρχείου.Glib::IO_HUP - Κλήση της μεθόδου σας όταν διακόψει (η σύνδεση έχει διακοπεί συνήθως για διοχετεύσεις και υποδοχές).Glib::IO_IN - Κλήση της μεθόδου σας όταν υπάρχουν δεδομένα έτοιμα για ανάγνωση στον περιγραφέα αρχείου σας.Glib::IO_OUT - Κλήση της μεθόδου σας όταν ο περιγραφέας αρχείου είναι έτοιμος για εγγραφή.Glib::IO_PRI - Κλήση της μεθόδου σας όταν ο περιγραφέας αρχείου έχει επείγοντα δεδομένα για ανάγνωση.Glib::RefPtr&lt;Gtk::Adjustment&gt; Gtk::Adjustment::create(
  double value,
  double lower,
  double upper,
  double step_increment = 1,
  double page_increment = 10,
  double page_size = 0);Glib::RefPtr&lt;Gtk::Application&gt; app = Gtk::Application::create(argc, argv, "org.gtkmm.examples.base")·Glib::RefPtr&lt;Gtk::Clipboard&gt; refClipboard = Gtk::Clipboard::get();

//Προορισμοί:
std::vector&lt;Gtk::TargetEntry&gt; targets;
targets.push_back( Gtk::TargetEntry("example_custom_target") );
targets.push_back( Gtk::TargetEntry("UTF8_STRING") );

refClipboard-&gt;set( targets,
    sigc::mem_fun(*this, &amp;ExampleWindow::on_clipboard_get),
    sigc::mem_fun(*this, &amp;ExampleWindow::on_clipboard_clear) );Glib::RefPtr&lt;Gtk::ListStore&gt; refListStore =
    Gtk::ListStore::create(m_Columns);Glib::RefPtr&lt;Gtk::RecentInfo&gt; info;
try
{
  info = recent_manager-&gt;lookup_item(uri);
}
catch(const Gtk::RecentManagerError&amp; ex)
{
  std::cerr &lt;&lt; "RecentManagerError: " &lt;&lt; ex.what() &lt;&lt; std::endl;
}
if (info)
{
  // το στοιχείο βρέθηκε
}Glib::RefPtr&lt;Gtk::RecentManager&gt; recent_manager = Gtk::RecentManager::get_default();
recent_manager-&gt;add_item(uri);Glib::RefPtr&lt;Gtk::TextBuffer::Mark&gt; refMark =
    refBuffer-&gt;create_mark(iter);Glib::RefPtr&lt;Gtk::TextBuffer::Tag&gt; refTagMatch =
    Gtk::TextBuffer::Tag::create();
refTagMatch-&gt;property_background() = "orange";Glib::RefPtr&lt;Gtk::TextBuffer::TagTable&gt; refTagTable =
    Gtk::TextBuffer::TagTable::create();
refTagTable-&gt;add(refTagMatch);
//Ας ελπίσουμε ότι μια μελλοντική έκδοση του <application>gtkmm</application> θα έχει μια μέθοδο set_tag_table(),
//για χρήση μετά τη δημιουργία της ενδιάμεσης μνήμης.
Glib::RefPtr&lt;Gtk::TextBuffer&gt; refBuffer =
    Gtk::TextBuffer::create(refTagTable);Glib::RefPtr&lt;Gtk::TextChildAnchor&gt; refAnchor =
    refBuffer-&gt;create_child_anchor(iter);Glib::RefPtr&lt;Gtk::TreeModelSort&gt; sorted_model =
    Gtk::TreeModelSort::create(model);
sorted_model-&gt;set_sort_column(columns.m_col_name, Gtk::SORT_ASCENDING);
treeview.set_model(sorted_model);Glib::RefPtr&lt;Gtk::TreeSelection&gt; refTreeSelection =
    m_TreeView.get_selection();Glib::RefPtr&lt;Gtk::UIManager&gt; m_refUIManager =
    Gtk::UIManager::create();
m_refUIManager-&gt;insert_action_group(m_refActionGroup);
add_accel_group(m_refUIManager-&gt;get_accel_group());Glib::ustringGlib::ustring and std::iostreamsGlib::ustring strText = row[m_Columns.m_col_text];
int number = row[m_Columns.m_col_number];Glib::ustring ui_info =
    "&lt;ui&gt;"
    "  &lt;menubar name='MenuBar'&gt;"
    "    &lt;menu action='MenuFile'&gt;"
    "      &lt;menuitem action='New'/&gt;"
    "      &lt;menuitem action='Open'/&gt;"
    "      &lt;separator/&gt;"
    "      &lt;menuitem action='Quit'/&gt;"
    "    &lt;/menu&gt;"
    "    &lt;menu action='MenuEdit'&gt;"
    "      &lt;menuitem action='Cut'/&gt;"
    "      &lt;menuitem action='Copy'/&gt;"
    "      &lt;menuitem action='Paste'/&gt;"
    "    &lt;/menu&gt;"
    "  &lt;/menubar&gt;"
    "  &lt;toolbar  name='ToolBar'&gt;"
    "    &lt;toolitem action='Open'/&gt;"
    "    &lt;toolitem action='Quit'/&gt;"
    "  &lt;/toolbar&gt;"
    "&lt;/ui&gt;";

m_refUIManager-&gt;add_ui_from_string(ui_info);Glib::ustring ui_info =
    "&lt;ui&gt;"
    "  &lt;popup name='PopupMenu'&gt;"
    "    &lt;menuitem action='ContextEdit'/&gt;"
    "    &lt;menuitem action='ContextProcess'/&gt;"
    "    &lt;menuitem action='ContextRemove'/&gt;"
    "  &lt;/popup&gt;"
    "&lt;/ui&gt;";

m_refUIManager-&gt;add_ui_from_string(ui_info);ΠλέγμαΟμάδεςGtk::Alignment
Gtk::Arrow
Gtk::AspectFrame
Gtk::Bin
Gtk::Box
Gtk::Button
Gtk::CheckButton
Gtk::Fixed
Gtk::Frame
Gtk::Grid
Gtk::Image
Gtk::Label
Gtk::MenuItem
Gtk::Notebook
Gtk::Paned
Gtk::RadioButton
Gtk::Range
Gtk::ScrolledWindow
Gtk::Separator
Gtk::Table (παρωχημένο από την έκδοση 3.4 του <application>gtkmm</application>)
Gtk::ToolbarGtk::επιλογές εφαρμογής και γραμμής εντολώνGtk::Box(Gtk::Orientation orientation = Gtk::ORIENTATION_HORIZONTAL, int spacing = 0);
void set_spacing(int spacing);
void set_homogeneous(bool homogeneous = true);Gtk::Button* pButton = new Gtk::Button("_Something", true);Gtk::CellRendererToggle* pRenderer =
    Gtk::manage( new Gtk::CellRendererToggle() );
pRenderer-&gt;signal_toggled().connect(
    sigc::bind( sigc::mem_fun(*this,
        &amp;Example_TreeView_TreeStore::on_cell_toggled), m_columns.dave)
);Το Gtk::ComboBox τώρα παράγεται από CellLayout, επιτρέποντας ευκολότερη διάταξη και στοίχιση των <classname>Gtk::CellRenderer</classname> του.Gtk::DrawingArea myArea;
Cairo::RefPtr&lt;Cairo::Context&gt; myContext = myArea.get_window()-&gt;create_cairo_context();
myContext-&gt;set_source_rgb(1.0, 0.0, 0.0);
myContext-&gt;set_line_width(2.0);Gtk::Entry* entry = m_Combo.get_entry();
if (entry)
{
  // The Entry shall receive focus-out events.
  entry-&gt;add_events(Gdk::FOCUS_CHANGE_MASK);

  // Alternatively you can connect to m_Combo.signal_changed().
  entry-&gt;signal_changed().connect(sigc::mem_fun(*this,
    &amp;ExampleWindow::on_entry_changed) );

  entry-&gt;signal_activate().connect(sigc::mem_fun(*this,
    &amp;ExampleWindow::on_entry_activate) );

  entry-&gt;signal_focus_out_event().connect(sigc::mem_fun(*this,
    &amp;ExampleWindow::on_entry_focus_out_event) );
}Gtk::EventBox()·Το Gtk::Label υποστηρίζει κάποια απλή μορφοποίηση, για παράδειγμα επιτρέπει τη δημιουργία κάποιου έντονου, χρωματιστού ή μεγαλύτερου κειμένου. Μπορείτε να το κάνετε δίνοντας μια συμβολοσειρά στο <methodname>set_markup()</methodname>, χρησιμοποιώντας τη <ulink url="http://developer.gnome.org/pango/unstable/PangoMarkupFormat.html">σύνταξη σήμανσης Pango</ulink>. Για παράδειγμα, <code> &lt;b&gt;bold text&lt;/b&gt; και &lt;s&gt;strikethrough text&lt;/s&gt; </code> .Gtk::TreeModel::Children children = row.children();Gtk::TreeModel::Row row = *iter;Gtk::TreeModel::Row row = m_refModel-&gt;children()[5]; //The fifth row.
if(row)
  refTreeSelection-&gt;select(row);Gtk::TreeModel::iterator iter = m_Combo.get_active();
if(iter)
{
  Gtk::TreeModel::Row row = *iter;

  //Λήψη των δεδομένων για την επιλεγμένη γραμμή, χρησιμοποιώντας τη
  //γνώση μας του προτύπου δένδρου:
  int id = row[m_Columns.m_col_id];
  set_something_id_chosen(id); //Η δικιά σας συνάρτηση.
}
else
  set_nothing_chosen(); //Η δικιά σας συνάρτηση.Gtk::TreeModel::iterator iter = m_refListStore-&gt;append();Gtk::TreeModel::iterator iter = m_refModel-&gt;children().begin()
if(iter)
  refTreeSelection-&gt;select(iter);Gtk::TreeModel::iterator iter_child =
    m_refTreeStore-&gt;append(row.children());Gtk::TreeView::Column* pColumn =
  Gtk::manage(new Gtk::TreeView::Column("Icon Name"));

// m_columns.icon and m_columns.iconname είναι στήλες στο μοντέλο.
// pColumn είναι η στήλη στην προβολή δένδρου:
pColumn-&gt;pack_start(m_columns.icon, /* expand= */ false);
pColumn-&gt;pack_start(m_columns.iconname);

m_TreeView.append_column(*pColumn);Gtk::TreeView::Column* pColumn = treeview.get_column(0);
if(pColumn)
  pColumn-&gt;set_sort_column(m_columns.m_col_id);Gtk::Widget* pMenubar = m_refUIManager-&gt;get_widget("/MenuBar");
pBox-&gt;add(*pMenuBar, Gtk::PACK_SHRINK);Gtk::Window window;
window.set_default_size(200, 200);Πηγαία αρχεία κωδικοποιημένα με το χέριΚατασκευαστές κωδικοποίησης με το χέριΧειριστείτε τις επιλογές στη <function>main()</function> και κρύψτε τες από την <classname>Gtk::Application</classname> ορίζοντας <literal>argc = 1</literal> στην κλήση στην <methodname>Gtk::Application::create()</methodname>.Χειρισμός <literal>button_press_event</literal>Ο χειρισμός ενός συμβάντος Χ δεν επηρεάζει τα άλλα σήματα του γραφικού συστατικού. Αν χειρίζεστε το <literal>button_press_event</literal> για την <classname>Gtk::Button</classname>, θα μπορείτε ακόμα να πάρετε το σήμα <literal>clicked</literal>. Εκπέμπονται (σχεδόν) ταυτόχρονα.Κεφαλίδες και σύνδεσηHello WorldHello World 2Hello World στη <application>gtkmm</application>HelloWorld::HelloWorld()
:
  m_button ("Hello World")
{
  set_border_width(10)·
  m_button.signal_clicked().connect(sigc::mem_fun(*this,
    &amp;HelloWorld::on_button_clicked));
  add(m_button);.
  m_button.show();
}Ιδού μερικά παραδείγματα κανονικής διαχείρισης μνήμης C++:Ιδού μια λίστα μερικών από αυτά τα γραφικά συστατικά:Να ένα απλό παράδειγμα που πακετάρει 100 κουμπιά εναλλαγής σε ένα κυλιόμενο παράθυρο. Δοκιμάστε αυξομείωση του παραθύρου για να δείτε την αντίδραση των γραμμών κύλισης.Ιδού ένα μικρό τμήμα κώδικα για σύζευξη τους όλων μαζί: (Σημειώστε ότι συνήθως δεν θα πρέπει να φορτώνετε την εικόνα κάθε φορά στον χειριστή σήματος σχεδίασης! Εμφανίζεται απλά εδώ για να τα διατηρήσει όλα μαζί.)Να ένα πολύ απλό παράδειγμα, που δείχνει μια λειτουργία μεταφοράς και απόθεσης <literal>Copy</literal>:Ιδού ένα παράδειγμα μεθόδου επανάκλησης:Ιδού ένα παράδειγμα προγράμματος που σχεδιάζει κάποιο κείμενο, κάποιο από αυτό ανάποδα. Το κεφάλαιο εκτύπωσης περιέχει ένα άλλο <link linkend="sec-printing-example">παράδειγμα</link> σχεδίασης κειμένου.Ιδού ένα παράδειγμα απλού προγράμματος που σχεδιάζει μια εικόνα.Εδώ είναι ένα απόσπασμα από μια συνεδρία της <application>gdb</application>. Μόνο τα πιο ενδιαφέροντα μέρη της εξόδου εμφανίζονται. <placeholder-1/> Μπορείτε να δείτε ότι η εξαίρεση προκλήθηκε από το <filename>without_signal.cc</filename>, γραμμή 6 (<code>throw "Something";</code>).Να κάποιο παράδειγμα κώδικα από το <filename>gtkmm/demos/gtk-demo/example_icontheme.cc</filename>, που έχει ένα εικονίδιο pixbuf και ένα όνομα κειμένου στην ίδια στήλη:Να ο πηγαίος κώδικας για το παράδειγμα που παρήγαγε τα παραπάνω στιγμιότυπα. Όταν εκτελείτε αυτό το παράδειγμα, δώστε έναν αριθμό μεταξύ 1 και 3 ως επιλογή της γραμμής εντολών, για να δείτε σε χρήση τις διαφορετικές επιλογές συσκευασίας.Εδώ ορίζουμε μια νέα κλάση που λέγεται <classname>OverriddenButton</classname>, που κληρονομεί από την <classname>Gtk::Button</classname>. Το μόνο που αλλάζουμε είναι η μέθοδος <methodname>on_clicked()</methodname>, που καλείται όποτε η <classname>Gtk::Button</classname> εκπέμπει το σήμα <literal>clicked</literal>. Αυτή η μέθοδος εκτυπώνει "Hello World" στην <literal>stdout</literal> και έπειτα καλεί την αρχική υποκατεστημένη μέθοδο, για να επιτρέψει στην <classname>Gtk::Button</classname> να κάνει ό,τι θα είχε κάνει αν δεν είχε αντικατασταθεί.Ιδού ένα απλό παράδειγμα: <placeholder-1/>Ιδού ένα ελαφρώς μεγαλύτερο παράδειγμα υποδοχών σε δράση:Να ένα παράδειγμα μιας <classname>SpinButton</classname> σε ενέργεια:Ιδού ένα παράδειγμα ενός χειριστή σήματος που συνδέθηκε σε ένα σήμα:Ιδού ένα παράδειγμα απλού προγράμματος που σχεδιάζει ένα τόξο, έναν κύκλο και μια έλλειψη σε μια περιοχή σχεδίασης.Ιδού ένα παράδειγμα αυτής της τεχνικής:Ιδού ο κατασκευαστής για το γραφικό συστατικό <classname>Box</classname> και οι μέθοδοι που ορίζουν τις επιλογές συσκευασίας ανά περιέκτη: <placeholder-1/>. Το πέρασμα του <literal>true</literal> στη <methodname>set_homogeneous()</methodname> θα κάνει όλα τα περιεχόμενα γραφικά συστατικά να είναι του ίδιου μεγέθους. Η <parameter>spacing</parameter> είναι ένας (ελάχιστος) αριθμός εικονοστοιχείων που αφήνεται μεταξύ κάθε γραφικού συστατικού.Πώς δουλεύει το gettextΠώς να χρησιμοποιήσετε το git για μεταφραστές GNOMEΌμως, η <application>Glib</application> ορίζει την υποστήριξη <function>gettext()</function> μακροεντολών που είναι πιο σύντομοι συσκευαστές σε μια εύχρηστη φόρμα. Για να χρησιμοποιήσετε αυτές τις μακροεντολές, συμπεριλάβετε την <literal>&lt;glibmm/i18n.h&gt;</literal> και έπειτα, για παράδειγμα, αντικαταστήστε: <placeholder-1/> με: <placeholder-2/>Όμως, απαιτείται φροντίδα όταν συγγράφονται προγράμματα με βάση την <application>gtkmm</application> χρησιμοποιώντας πολλαπλά νήματα εκτέλεσης, που προκύπτει από το γεγονός ότι η <application>libsigc++</application> και ειδικά η <classname>sigc::trackable</classname>, δεν είναι ασφαλή νήματα. Αυτό οφείλεται στο ότι καμιά σύνθετη αλληλεπίδραση που συμβαίνει πίσω από τη σκηνή κατά τη χρήση της <application>libsigc++</application> δεν προστατεύεται από έναν αμοιβαίο αποκλεισμό ή άλλο μέσο συγχρονισμού. <placeholder-1/>Όμως, αυτό δεν επιτρέπει κανένα στοιχείο ελέγχου του οποίου τα στοιχεία μπορούν να μετακινηθούν και όπου μπορούν να αποτεθούν. Αν χρειάζεστε αυτόν τον πρόσθετο έλεγχο, τότε μπορείτε να δημιουργήσετε ένα παράγωγο <literal>Gtk::TreeModel</literal> από τα <literal>Gtk::TreeStore</literal> ή <literal>Gtk::ListStore</literal> και να αντικαταστήσετε τις εικονικές μεθόδους <literal>Gtk::TreeDragSource::row_draggable()</literal> και <literal>Gdk::TreeDragDest::row_drop_possible()</literal>. Μπορείτε να εξετάσετε τα παρεχόμενα <literal>Gtk::TreeModel::Path</literal>s και να επιτρέψετε ή να απορρίψετε τη μεταφορά ή απόθεση επιστρέφοντας <literal>true</literal> ή <literal>false</literal>.Όμως, αυτό είναι ακόμα πιο απλό όταν χρησιμοποιείται η μακροεντολή <function>PKG_CHECK_MODULES()</function> σε ένα τυπικό αρχείο configure.ac με autoconf και automake. Για παράδειγμα: <placeholder-1/>. Αυτό ελέγχει την παρουσία του gtkmm και ορίζει τα MYAPP_LIBS και MYAPP_CFLAGS για χρήση στα αρχεία σας Makefile.am.Όμως, μπορεί να μην θέλετε οι νέες τιμές να αποθηκευτούν αμέσως. Για παράδειγμα, μπορεί να θέλετε να περιορίσετε την είσοδο σε συγκεκριμένους χαρακτήρες ή περιοχές τιμών.Όμως, προφανώς αποφεύγετε ήδη γυμνούς πίνακες char* και αριθμητικούς δείκτες χρησιμοποιώντας την <classname>std::string</classname>, έτσι χρειάζεστε μόνο να ξεκινήσετε χρησιμοποιώντας στη θέση τους <classname>Glib::ustring</classname>. Δείτε το κεφάλαιο <link linkend="sec-basics-ustring">Βασικά</link> για την <classname>Glib::ustring</classname>.I've been embedded.
A plug was addedINTLTOOL_FILES = intltool-extract.in \
                 intltool-merge.in \
                 intltool-update.inIT_PROG_INTLTOOL([0.35.0])

GETTEXT_PACKAGE=programname
AC_SUBST(GETTEXT_PACKAGE)
AC_DEFINE_UNQUOTED([GETTEXT_PACKAGE], ["$GETTEXT_PACKAGE"],
                   [The domain to use with gettext])
AM_GLIB_GNU_GETTEXT

PROGRAMNAME_LOCALEDIR=[${datadir}/locale]
AC_SUBST(PROGRAMNAME_LOCALEDIR)ΙδανικόΙδανικά, θα θέλαμε να <ulink url="http://www.gtkmm.org/bugs.shtml">δώσετε μια προσθήκη</ulink> στο αρχείο <filename>docs/tutorial/C/gtkmm-tutorial-in.xml</filename>. Αυτό το αρχείο είναι προς το παρόν στην ενότητα <literal>gtkmm-documentation</literal> στο GNOME git.Αδρανείς συναρτήσειςΑν ένα ειδικό αντικείμενο κλάσης προέρχεται από την <classname>sigc::trackable</classname>, μόνο ένα νήμα πρέπει να δημιουργήσει αντικείμενα <classname>sigc::slot</classname> που αναπαριστούν οποιεσδήποτε μη στατικές μεθόδους της κλάσης καλώντας την <function>sigc::mem_fun()</function>. Το πρώτο νήμα για να δημιουργήσει μια τέτοια υποδοχή πρέπει να θεωρηθεί ως κάτοχος του σχετικού αντικειμένου για τον σκοπό της δημιουργίας παραπέρα υποδοχών αναφορικά με <emphasis>οποιαδήποτε</emphasis> από τις μη στατικές μεθόδους που χρησιμοποιούν αυτή τη συνάρτηση, ή αδειάζοντας αυτές τις υποδοχές αποσυνδέοντας τες ή καταστρέφοντας το ανιχνεύσιμο αντικείμενο.Αν ένας προγραμματιστής δεν χρειάζεται ένα γραφικό συστατικό εμβέλειας κλάσης, ένα γραφικό συστατικό εμβέλειας συνάρτησης μπορεί επίσης να χρησιμοποιηθεί. Τα πλεονεκτήματα της εμβέλειας συνάρτησης πάνω στην εμβέλεια κλάσης είναι η αυξημένη απόκρυψη δεδομένων και οι μειωμένες εξαρτήσεις. <placeholder-1/>Αν ένας προγραμματιστής δεν χρειάζεται δυναμική κατανομή μνήμης, μπορούν να χρησιμοποιηθούν αυτόματα γραφικά συστατικά στην εμβέλεια της κλάσης. Ένα πλεονέκτημα των αυτόματων γραφικών συστατικών σε εμβέλεια κλάσης είναι ότι η διαχείριση μνήμης ομαδοποιείται σε μια θέση. Ο προγραμματιστής δεν διακινδυνεύει διαρροές μνήμης από αποτυχία <literal>delete</literal> ενός γραφικού συστατικού.Αν όλα δούλεψαν σωστά, θα πρέπει να μπορείτε να δομήσετε την <application>gtkmm</application> και όλες τις εξαρτήσεις της από το git εκτελώντας την <command>jhbuild build</command> (ή, αν δεν ορίσατε την <application>gtkmm</application> στη μεταβλητή <varname>modules</varname>, με την εντολή <command>jhbuild build gtkmm</command>).If for some reason the <classname>Socket</classname> couldn't attach the <classname>Plug</classname>, the window would look something like this:Αν η απαρίθμηση δεν είναι μια <classname>GType</classname>, πρέπει να περάσετε μια τρίτη παράμετρο NO_GTYPE. Αυτή είναι η περίπτωση όταν δεν υπάρχει συνάρτηση <function>*_get_type()</function> για την απαρίθμηση C, αλλά προσέξτε ότι δεν χρειάζεται μόνο να συμπεριλάβετε μια πρόσθετη κεφαλίδα για αυτήν τη συνάρτηση. Θα πρέπει επίσης να στείλετε ένα σφάλμα στην API C, επειδή όλες οι απαριθμήσεις πρέπει να καταχωριστούν ως GTypes.Αν υπάρχουν πολλές λήψεις εξαιρέσεων πριν την ενδιαφέρουσα μη ληφθείσα, αυτή η μέθοδος μπορεί να είναι κουραστική. Μπορεί να αυτοματοποιηθεί με τις ακόλουθες εντολές της <application>gdb</application>. <placeholder-1/> Αυτές οι εντολές θα εκτυπώσουν μια οπισθοανίχνευση από κάθε <code>throw</code> και θα συνεχίσουν. Η οπισθοανίχνευση από την τελευταία (ή πιθανόν την προτελευταία) <code>throw</code> πριν σταματήσει το πρόγραμμα, είναι η ενδιαφέρουσα.Αν αυτή είναι η πρώτη φορά που χρησιμοποιείτε ένα πρόγραμμα που χρησιμοποιεί τον σκελετό πρόσφατων αρχείων, ο διάλογος μπορεί να είναι κενός στην αρχή. Αλλιώς πρέπει να εμφανίσει έναν κατάλογο των πρόσφατα χρησιμοποιημένων καταχωρισμένων εγγράφων από άλλες εφαρμογές.Αν ενδιαφέρεστε να βοηθήσετε την ανάπτυξη της <application>gtkmm</application>, ή να διορθώσετε ένα σφάλμα στην <application>gtkmm</application>, θα χρειαστείτε προφανώς να δομήσετε την έκδοση ανάπτυξης της <application>gtkmm</application>. Όμως, δεν θα πρέπει να εγκαταστήσετε μια έκδοση ανάπτυξης πάνω στη σταθερή έκδοση. Αντίθετα, θα πρέπει να την εγκαταστήσετε δίπλα στην υπάρχουσα εγκατάσταση <application>gtkmm</application>, σε μια ξεχωριστή διαδρομή.Αν χρησιμοποιείτε μια <application>gettext</application> άμεσα, μπορείτε μόνο να σημειώ σετε τις συμβολοσειρές για μετάφραση αν είναι στο αρχείο πηγαίου κώδικα. Όμως, αν χρησιμοποιείτε <application>intltool</application>, μπορείτε να σημειώσετε τις συμβολοσειρές για μετάφραση σε μια ποικιλία άλλων μορφών αρχείων, συμπεριλαμβάνοντας αρχεία διεπαφής χρήστη <application>Glade</application>, xml, <ulink url="http://standards.freedesktop.org/desktop-entry-spec/latest/">.desktop files</ulink> και πολλά περισσότερα. Έτσι, αν έχετε σχεδιάσει κάποια διεπαφή χρήστη της εφαρμογής σε <application>Glade</application>, τότε προσθέστε επίσης τα αρχεία σας <filename>.glade</filename> στον κατάλογο στο <literal>POTFILES.in</literal>.Αν καλέσετε τη <methodname>Gtk::TreeView::set_reorderable()</methodname>, τότε τα στοιχεία της προβολής δένδρου μπορούν να μετακινηθούν μέσα στην ίδια προβολή δένδρου. Αυτό δείχνεται στο παράδειγμα <classname>TreeStore</classname>.Αν αντιγράφετε το πηγαίο δένδρο σκελετού σε mm-common και αντικαταστήσετε το κείμενο του δεσμευτικού θέσης, τότε θα έχετε ήδη κατάλληλα αρχεία <filename>Makefile.am</filename> και <filename>Doxyfile.in</filename>. Με την εγκατάσταση δόμησης mm-common, η λίστα των αρχείων εισόδου Doxygen δεν ορίζεται στο αρχείο ρυθμίσεων Doxygen, αλλά περνά από την <command>make</command> στην τυπική είσοδο της <command>doxygen</command>. Η λίστα αρχείων εισόδου ορίζεται από τη μεταβλητή <varname>doc_input</varname> στο αρχείο <filename>Makefile.am</filename>.Αν αντιγράψετε μια <classname>RefPtr</classname>, για παράδειγμα <placeholder-1/> , ή αν την περάσετε ως ένα όρισμα μεθόδου ή τύπο επιστροφής, τότε η <classname>RefPtr</classname> θα κάνει κάθε απαραίτητη αναφορά για να εξασφαλίσει ότι το στιγμιότυπο δεν θα καταστραφεί μέχρι η τελευταία <classname>RefPtr</classname> να βγει εκτός εμβέλειας.Αν αποφασίσετε να συνεισφέρετε, παρακαλούμε στείλτε τη συνεισφορά σας στην ταχυδρομική λίστα <application>gtkmm</application> στο <ulink url="mailto:gtkmm-list@gnome.org">&lt;gtkmm-list@gnome.org&gt;</ulink>. Επίσης, να ξέρετε ότι όλο αυτό το έγγραφο είναι ελεύθερο και οποιαδήποτε προσθήκη δώσετε πρέπει να είναι επίσης ελεύθερη. Δηλαδή, τα άτομα πρέπει να μπορούν να χρησιμοποιήσουν οποιοδήποτε τμήμα των παραδειγμάτων σας στα προγράμματά τους και αντίγραφα αυτού του εγγράφου (συμπεριλαμβανομένης της συνεισφορά σας) μπορούν να διανεμηθούν ελεύθερα.Αν δεν θέλετε να ψάξετε για ένα συγκεκριμένο URI, αλλά αντίθετα θέλετε να πάρετε έναν κατάλογο όλων των πρόσφατα χρησιμοποιημένων στοιχείων, η <classname>RecentManager</classname> παρέχει τη συνάρτηση <methodname>get_items()</methodname>. Η τιμή επιστροφής αυτής της συνάρτησης είναι μια <classname>std::vector</classname> όλων των πρόσφατα χρησιμοποιημένων αρχείων. Ο παρακάτω κώδικας δείχνει πώς μπορείτε να πάρετε έναν κατάλογο των πρόσφατα χρησιμοποιημένων αρχείων:Αν έχετε δημιουργήσει μια <classname>Tag</classname> και την προσθέσατε στην <classname>TagTable</classname>, μπορεί να εφαρμόσετε αυτήν την ετικέτα σε μέρος της <classname>TextBuffer</classname> έτσι ώστε κάποιο κείμενο να εμφανίζεται με αυτήν τη μορφοποίηση. Ορίζετε την αρχή και το τέλος της περιοχής του κειμένου ορίζοντας <classname>Gtk::TextBuffer::iterator</classname>s. Για παράδειγμα:Αν περάσετε <literal>true</literal> στη μέθοδο <methodname>set_activates_default()</methodname>, πατώντας εισαγωγή στη <classname>Gtk::Entry</classname> θα ενεργοποιήσει το προεπιλεγμένο γραφικό συστατικό για το παράθυρο που περιέχει την <classname>Gtk::Entry</classname>. Αυτό είναι ιδιαίτερα χρήσιμο σε πλαίσια διαλόγων. Το προεπιλεγμένο γραφικό συστατικό είναι συνήθως ένα από τα κουμπιά διαλόγου, που π.χ. θα κλείσει το πλαίσιο διαλόγου. Για τον ορισμό ενός γραφικού συστατικού ως το προεπιλεγμένο γραφικό συστατικό, χρησιμοποιήστε τις <methodname>Gtk::Widget::set_can_default()</methodname> και <methodname>Gtk::Widget::grab_default()</methodname>.Αν μοιράζεστε ένα αντικείμενο προσαρμογής μεταξύ ενός γραφικού συστατικού γραμμής κύλισης και ενός προβολής κειμένου (TextView), ο χειρισμός της γραμμής κύλισης θα προσαρμόσει αυτόματα το γραφικό συστατικό προβολής κειμένου. Μπορείτε να το ρυθμίσετε όπως αυτό:Αν δοκιμάσετε να σχεδιάσετε γραμμές πλάτους ενός εικονοστοιχείου, μπορεί να σημειώσετε ότι η γραμμή μερικές φορές παρουσιάζεται θολωμένη και πλατύτερη από όσο θα έπρεπε να είναι. Αυτό συμβαίνει επειδή το Cairo θα προσπαθήσει να σχεδιάσει από την επιλεγμένη θέση και στις δυο πλευρές (μισή σε καθεμιά), έτσι αν είσαστε τοποθετημένοι ακριβώς στην τομή των εικονοστοιχείων και θέλετε μια γραμμή με πλάτος ένα εικονοστοιχείο, το Cairo θα προσπαθήσει να χρησιμοποιήσει το μισό κάθε γειτονικού εικονοστοιχείου, που δεν είναι δυνατό (ένα εικονοστοιχείο είναι η μικρότερη δυνατή μονάδα). Αυτό συμβαίνει όταν το πλάτος της γραμμής είναι ένας περιττός αριθμός εικονοστοιχείων (όχι μόνο ένα εικονοστοιχείο).Αν χρησιμοποιείτε έναν χειριστή σήματος για λήψη του ίδιου σήματος από αρκετά γραφικά συστατικά, μπορεί να σας αρέσει ο χειριστής σήματος να δεχτεί μερικές πρόσθετες πληροφορίες. Για παράδειγμα, μπορεί να θελήσετε να μάθετε ποιο κουμπί πατήθηκε. Μπορείτε να το κάνετε με την <function>sigc::bind()</function>. Εδώ είναι κάποιος κώδικας από το παράδειγμα, <link linkend="sec-helloworld2">helloworld2</link>. <placeholder-1/> Αυτό λέει ότι θέλουμε το σήμα να στείλει ένα πρόσθετο όρισμα <classname>Glib::ustring</classname> στον χειριστή σήματος και ότι η τιμή αυτού του ορίσματος πρέπει να είναι "button 1". Φυσικά θα χρειαστεί να προσθέσουμε αυτό το πρόσθετο όρισμα στη δήλωση του χειριστή σήματός μας: <placeholder-2/> Φυσικά, ένας κανονικός χειριστής σήματος "clicked" δεν θα έχει ορίσματα.Αν θέλετε να βοηθήσετε στην ανάπτυξη της <application>gtkmm</application> ή να πειραματιστείτε με νέα χαρακτηριστικά, μπορείτε επίσης να εγκαταστήσετε τη <application>gtkmm</application> από το git. Οι περισσότεροι χρήστες δεν θα χρειαστεί ποτέ να το κάνουν αυτό, αλλά αν ενδιαφέρεστε να βοηθήσετε στην ανάπτυξη της <application>gtkmm</application>, δείτε το παράρτημα <link linkend="chapter-working-with-source">Εργασία με τον πηγαίο κώδικα της gtkmm</link>.Αν θέλετε να καταχωρίσετε ένα αρχείο με μεταδεδομένα, μπορείτε να περάσετε μια παράμετρο <classname>RecentManager::Data</classname> στην <methodname>add_item()</methodname>. Τα μεταδεδομένα που μπορούν να οριστούν στο συγκεκριμένο στοιχείο του αρχείου είναι ως εξής:Αν θέλετε να ορίσετε μια μέθοδο που καλείται όταν τίποτα άλλο δεν συμβαίνει, χρησιμοποιήστε την ακόλουθη:Αν θέλετε να μάθετε περισσότερα για τους έξυπνους δείκτες, μπορείτε να ψάξετε σε αυτά τα βιβλία: <placeholder-1/>Αν έχετε σχεδιάσει μια σειρά γραμμών που σχηματίζουν μια διαδρομή, μπορεί να θελήσετε να τις ενώσετε μαζί με έναν συγκεκριμένο τρόπο. Το Cairo προσφέρει τρεις διαφορετικούς τρόπους για ένωση γραμμών μεταξύ τους: μύτη, λοξότμηση και στρογγυλό. Αυτά εμφανίζονται παρακάτω:Αν δεν έχετε χρησιμοποιήσει ποτέ πριν ένα πακέτο εργαλείων συσκευασίας, μπορεί να πάρει κάμποσο για να το χρησιμοποιήσετε. Θα βρείτε προφανώς, όμως, ότι δεν χρειάζεστε να βασίζεστε σε οπτικές μορφές επεξεργαστών τόσο πολύ όσο θα πρέπει με άλλα πακέτα εργαλείων.Αν η διανομή σας δεν παρέχει ένα προκατασκευασμένο πακέτο της <application>gtkmm</application>, ή αν θέλετε να εγκαταστήσετε μια διαφορετική έκδοση από την παρεχόμενη από τη διανομή σας, μπορείτε επίσης να εγκαταστήσετε τη <application>gtkmm</application> από την πηγή. Ο πηγαίος κώδικας για τη <application>gtkmm</application> μπορεί να μεταφορτωθεί από το <ulink url="http://www.gtkmm.org/"/>.Αν το πρόγραμμά σας είναι ελεύθερου λογισμικού, υπάρχει ένα ολόκληρο υποέργο του <literal>GNOME</literal> αφιερωμένο για να σας βοηθήσει να κάνετε μεταφράσεις, το <ulink url="https://live.gnome.org/TranslationProject/"><literal>GNOME</literal>Έργο μετάφρασης</ulink>.Υλοποίηση προσαρμοσμένης λογικής για επεξεργάσιμα κελιά.Στο <filename>configure.ac</filename>, <placeholder-1/>Στο <filename>skeleton/skeletonmm/Makefile.am</filename> πρέπει να αναφέρουμε τις σωστές τιμές για τις γενικές μεταβλητές που χρησιμοποιούνται αλλού στο σύστημα δόμησης:Στο <filename>skeleton/src/Makefile.am</filename> πρέπει να αναφέρουμε τις σωστές τιμές για τις γενικές μεταβλητές που χρησιμοποιούνται αλλού στο σύστημα δόμησης:Πέρα από την προσθήκη στοιχείων στον κατάλογο, μπορείτε επίσης να αναζητήσετε στοιχεία από τον κατάλογο και να τροποποιήσετε ή να αφαιρέσετε στοιχεία.Πέρα από την αλλαγή του URI ενός αρχείου, μπορείτε επίσης να αφαιρέσετε στοιχεία από τον κατάλογο, είτε ένα τη φορά είτε καθαρίζοντας τα όλα μονομιάς. Το πρώτο πραγματοποιείται με την <methodname>remove_item()</methodname>, το δεύτερο με την <methodname>purge_items()</methodname>.Πέρα από τη σχεδίαση βασικών ευθειών γραμμών, υπάρχει ένας αριθμός από πράγματα που μπορείτε να προσαρμόσετε σε μια γραμμή. Έχετε ήδη δει παραδείγματα ρύθμισης χρώματος και πλάτους γραμμής, αλλά υπάρχουν κι άλλα.Πέρα από τη σχεδίαση ευθειών γραμμών το Cairo επιτρέπει την εύκολη σχεδίαση καμπύλων γραμμών (τεχνικά μια κυβική εύκαμπτη καμπύλη Bézier) χρησιμοποιώντας τις συναρτήσεις <methodname>Cairo::Context::curve_to()</methodname> και <methodname>Cairo::Context::rel_curve_to()</methodname>. Αυτές οι συναρτήσεις παίρνουν συντεταγμένες για ένα σημείο προορισμού καθώς και συντεταγμένες για δύο σημεία 'ελέγχου'. Αυτό εξηγείται καλύτερα χρησιμοποιώντας ένα παράδειγμα, έτσι ας μπούμε μέσα.Γενικά, τα έργα τεχνοτροπίας gtkmm χρησιμοποιούν Doxygen, που διαβάζει ειδικά μορφοποιημένα σχόλια C++ και δημιουργεί τεκμηρίωση HTML. Μπορείτε να γράψετε αυτά τα σχόλια doxygen άμεσα στα αρχεία κεφαλίδας.Στην <classname>Gtk::Window</classname>, έχουμε επίσης αντικαταστήσει τον προεπιλεγμένο χειριστή (<methodname>on_key_release_event()</methodname>), και ένας άλλος χειριστής καλείται πριν τον προεπιλεγμένο χειριστή (<methodname>windowKeyReleaseBefore()</methodname>).Στην ενότητα <link linkend="sec-wrapping-hg-files">.hg and .ccg files</link> μπορείτε να μάθετε για τη χρησιμοποιούμενη σύνταξη σε αυτά τα αρχεία.Στο παραπάνω παράδειγμα σχεδιάσαμε καθετί χρησιμοποιώντας απόλυτες συντεταγμένες. Μπορείτε επίσης να σχεδιάσετε χρησιμοποιώντας σχετικές συντεταγμένες. Για μια ευθεία γραμμή, αυτό γίνεται με τη συνάρτηση <methodname>Cairo::Context::rel_line_to()</methodname>.Στις παρακάτω οδηγίες θα θεωρήσουμε ότι δεν χρησιμοποιείτε την <application>gettext</application> άμεσα, αλλά την <application>intltool</application>, που γράφτηκε ειδικά για το <literal>GNOME</literal>. Η <application>intltool</application> χρησιμοποιεί την <function>gettext()</function>, που εξάγει συμβολοσειρές από τον πηγαίο κώδικα, αλλά η <application>intltool</application> μπορεί επίσης να συνδυάσει συμβολοσειρές από άλλα αρχεία, για παράδειγμα από λεπτομέρειες μενού της επιφάνειας εργασίας και αρχεία πόρων γραφικής διεπαφής χρήστη όπως αρχεία <application>Glade</application>, σε τυπικά αρχεία <application>gettext</application><filename>.pot/.po</filename>.Στο ανώτατο επίπεδο Makefile.am: <placeholder-1/>Σε αυτές τις περιπτώσεις, θα πρέπει να προσθέσετε πρόσθετους χαρακτήρες στις συμβολοσειρές. Για παράδειγμα, χρησιμοποιήστε <literal>"jumps[noun]"</literal> και <literal>"jumps[verb]"</literal> αντί για απλώς <literal>"jumps"</literal> και αφαιρέστε τα πάλι έξω από την κλήση <function>gettext</function>. Αν προσθέτετε πρόσθετους χαρακτήρες θα πρέπει επίσης να προσθέσετε ένα σχόλιο για τους μεταφραστές πριν την κλήση της <function>gettext</function>. Τέτοια σχόλια θα εμφανιστούν στα αρχεία <filename>.po</filename>. Για παράδειγμα:Σε αυτό το παράδειγμα υπάρχουν τρεις χειριστές συμβάντων που καλούνται μετά τον προεπιλεγμένο χειριστή συμβάντος της <classname>Gtk::Window</classname>, ένας στην <classname>Gtk::Entry</classname>, ένας στην <classname>Gtk::Grid</classname> και ένας στην <classname>Gtk::Window</classname>.Σε αυτό το παράδειγμα υπάρχουν τρεις συντομεύσεις πληκτρολογίου: η <keycap>Alt</keycap>+<keycap>1</keycap> επιλέγει το πρώτο ραδιοπλήκτρο, η <keycap>Alt</keycap>+<keycap>2</keycap> επιλέγει το δεύτερο και το πλήκτρο <keycap>Esc</keycap> κρύβει (κλείνει) το παράθυρο. Ο προεπιλεγμένος χειριστής σήματος αντικαθίσταται, όπως περιγράφεται στην ενότητα <link linkend="sec-overriding-default-signal-handlers">Αντικατάσταση προεπιλεγμένων χειριστών σημάτων</link> στο παράρτημα.Σε αυτό το παράδειγμα, θα κατασκευάσουμε ένα μικρό, αλλά πλήρως λειτουργικό πρόγραμμα της <application>gtkmm</application> και θα σχεδιάσουμε μερικές γραμμές στο παράθυρο. Οι γραμμές σχεδιάζονται δημιουργώντας ένα μονοπάτι και έπειτα βάφοντας το. Το μονοπάτι δημιουργείται χρησιμοποιώντας τις συναρτήσεις <methodname>Cairo::Context::move_to()</methodname> και <methodname>Cairo::Context::line_to()</methodname>. Η συνάρτηση <methodname>move_to()</methodname> είναι παρόμοια με την πράξη της ανύψωσης του στυλού σας από το χαρτί και της τοποθέτησης του κάπου αλλού -- καμιά γραμμή δεν σχεδιάζεται μεταξύ του σημείου που ήσασταν και του σημείου που πήγατε. Για τη σχεδίαση μιας γραμμής μεταξύ δύο σημείων, χρησιμοποιήστε τη συνάρτηση <methodname>line_to()</methodname>.Σε αυτήν την ενότητα του μαθήματος, θα καλύψουμε το βασικό πρότυπο σχεδίασης του Cairo, θα περιγράψουμε κάθε βασικό στοιχείο σχεδίασης με κάποιες λεπτομέρειες (με παραδείγματα) και έπειτα θα παρουσιάσουμε μια απλή εφαρμογή που χρησιμοποιεί Cairo για τη σχεδίαση ενός προσαρμοσμένου γραφικού συστατικού ρολογιού.Στο <literal>src/Makefile.am</literal> σας, ενημερώστε το <literal>AM_CPPFLAGS</literal> σας για να προσθέσετε τον ακόλουθο προεπεξεργαστή ορισμού μακροεντολής:Αν η επανάκλησή σας, συγκρίνεται το διάνυσμα των διαθέσιμων προορισμών με αυτά που υποστηρίζει η εφαρμογή σας για επικόλληση. Μπορείτε να ενεργοποιήσετε ή να απενεργοποιήσετε το στοιχείο μενού επικόλλησης, ανάλογα με το αν η επικόλληση είναι προς το παρόν δυνατή. Για παράδειγμα:Στον χειριστή σήματός σας, θα πρέπει να εξετάσετε τη νέα τιμή και έπειτα να την αποθηκεύσει στο πρότυπο, αν αυτό είναι κατάλληλο για την εφαρμογή σας.Περιλαμβάνει τα άλλα αρχεία.Ανεξάρτητα ταξινομημένες προβολές του ίδιου προτύπουΓραμμή πληροφοριών (InfoBar)Η κληρονομικότητα μπορεί να χρησιμοποιηθεί για παραγωγή νέων γραφικών συστατικών. Η παραγωγή νέων γραφικών συστατικών σε κώδικα GTK+ C είναι τόσο περίπλοκη και επιρρεπής σε σφάλματα που σχεδόν κανένας κωδικοποιητής C δεν το κάνει. Ως προγραμματιστής C++, ξέρετε ότι η παραγωγή είναι μια βασική αντικειμενοστραφής τεχνική.ΑρχικοποίησηΕγκατάστασηΕγκατάσταση της <application>gtkmm</application> με <application>jhbuild</application>Εγκατάσταση από την πηγήΕγκατάσταση και χρήση της έκδοσης git της <application>gtkmm</application>Αντί για την επίπονη σύνδεση χειριστών σημάτων σε σήματα, μπορείτε να κάνετε απλά μια νέα κλάση που κληρονομεί από ένα γραφικό συστατικό - ας πούμε, ένα πλήκτρο - και έπειτα να αντικαταστήσετε τον προεπιλεγμένο χειριστή σήματος, όπως τον Button::on_clicked(). Αυτό μπορεί να είναι πιο απλό από την αγκίστρωση χειριστών σήματος για καθετί.Ενδιάμεσοι τύποιΔιεθνοποίηση και τοπικοποίησηΔιεθνοποίηση των εφαρμογών GNOMEREADME του εργαλείου διεθνοποίησης (Intltool)ΕισαγωγήΠαίρνει επίσης ένα προαιρετικό πρόσθετο όρισμα: <placeholder-1/>Ακολουθεί την ίδια μορφή. Ο αριθμός 3 στο τέλος του ονόματος τύπου δείχνει ότι ο χειριστής σήματος θα χρειαστεί τρία ορίσματα. Ο πρώτος τύπος στον κατάλογο τύπων είναι <type>void</type>, έτσι ώστε πρέπει να είναι ο τύπος επιστροφής του χειριστή σήματός μας. Οι ακόλουθοι τρεις τύποι είναι οι αποδεκτοί τύποι ορίσματος. Το πρωτότυπο του χειριστή σήματός μας μπορεί να μοιάζει με αυτό:Είναι συνηθισμένο για σύνδεση ενοτήτων να ανιχνεύουμε τον αριθμό έκδοσης της βιβλιοθήκης που συσκευάζεται. Έτσι, για παράδειγμα, αν η βιβλιοθήκη C είναι στην έκδοση 1.23.4, τότε η αρχική έκδοση της ενότητας σύνδεσης μπορεί να είναι 1.23.0. Όμως, αποφύγετε το ξεκίνημα με έναν άρτιο δευτερεύοντα αριθμό έκδοσης επειδή αυτό συνήθως δείχνει μια σταθερή έκδοση.Είναι καλή πρακτική να βάζετε όλες τις τροποποιήσεις στην κατάσταση γραφικών μεταξύ κλήσεων συναρτήσεων <methodname>save()</methodname>/<methodname>restore()</methodname>. Για παράδειγμα, αν έχετε μια λειτουργία που παίρνει μια αναφορά <classname>Cairo::Context</classname> ως ένα όρισμα, μπορείτε να την υλοποιήσετε ως εξής:Υποστηρίζει την επικόλληση 2 προορισμών - και του προσαρμοσμένου και ενός κειμένου που δημιουργεί μια παρουσίαση ελεύθερου κειμένου των προσαρμοσμένων δεδομένων.Χρησιμοποιεί τη <methodname>request_targets()</methodname> και το σήμα <literal>owner_change</literal> και απενεργοποιεί το κουμπί επικόλλησης αν δεν μπορεί να χρησιμοποιήσει ο,τιδήποτε στο πρόχειρο.Είναι αδύνατο να προβλέψετε τον απαραίτητο χώρο για κείμενο αφού έχει μεταφραστεί σε άλλες γλώσσες ή όταν εμφανίζεται με μια διαφορετική γραμματοσειρά. Στο Γιούνιξ είναι επίσης αδύνατο να προβλέψτε τις επιδράσεις κάθε θέματος και διαχειριστή παραθύρου.Είναι δυνατό συγκεκριμένες συμβολοσειρές να σημειωθούν ως <literal>ασαφείς</literal> στο αρχείο <filename>.po</filename> file. Αυτές οι μεταφράσεις δεν θα αντικαταστήσουν την αρχική συμβολοσειρά. Για να τις εμφανίσετε, αφαιρέστε απλά την ετικέτα <literal>ασαφής</literal>.Επανάληψη στις γραμμές προτύπουΕπαναλήπτεςJonathonJongsmaΚαλέστε απλά την μη σταθερή έκδοση της ίδιας συνάρτησης, αντί για τη δημιουργία σχεδόν διπλού κώδικα.Ακριβώς όπως οι κανονικοί δείκτες, μπορείτε να ελέγξετε αν η <classname>RefPtr</classname> δείχνει κάπου.Συμβάντα πληκτρολογίουΣυμβάντα πληκτρολογίου - Διάδοση συμβάντοςΣυμβάντα πληκτρολογίου - απλόKingKjellΕτικέταΟι ετικέτες είναι η κύρια μέθοδος τοποθέτησης μη επεξεργάσιμου κειμένου στα παράθυρα, για παράδειγμα η τοποθέτηση ενός τίτλου δίπλα σε ένα γραφικό συστατικό <classname>Entry</classname>. Μπορείτε να ορίσετε το κείμενο στον κατασκευαστή, ή αργότερα με τις μεθόδους <methodname>set_text()</methodname> ή <methodname>set_markup()</methodname>.Έλλειψη ιδιοτήτωνLaursenΑπαιτείται λιγότερος κώδικας C++.Ας κοιτάξουμε ένα παράδειγμα αντικατάστασης:Ας ρίξουμε μια ματιά σε ένα ελαφρά βελτιωμένο <literal>helloworld</literal>, που δείχνει τι έχουμε μάθει.Ας κοιτάξουμε τη μέθοδο του σήματος <literal>connect</literal>:Όπως τα πλαίσια ελέγχου, τα ραδιοπλήκτρα κληρονομούν επίσης από την <classname>Gtk::ToggleButton</classname>, αλλά αυτά δουλεύουν σε ομάδες και μόνο ένα RadioButton σε μια ομάδα μπορεί να επιλεγεί οποτεδήποτε.Όπως η <classname>TreeView</classname>, θα πρέπει προφανώς να βάλετε την <classname>TextView</classname> σας μέσα σε μια <classname>ScrolledWindow</classname> για να επιτρέψετε στον χρήστη να δει και να μετακινήσει ολόγυρα όλη την περιοχή κειμένου με γραμμές κύλισης.Παρόμοια, αντικαταστήστε όλα τα στιγμιότυπα της <varname>Joe Hacker</varname> με το όνομα του σκοπούμενου κατόχου πνευματικών δικαιωμάτων, που είσαστε προφανώς εσείς. Κάντε το ίδιο για τη διεύθυνση αλληλογραφίας <varname>joe@example.com</varname>.Τα άκρα της γραμμής μπορούν να έχουν διαφορετικές τεχνοτροπίες επίσης. Η προεπιλεγμένη τεχνοτροπία είναι να αρχίζει και να σταματά η γραμμή ακριβώς στα σημεία προορισμού της γραμμής. Αυτό λέγεται ένα κουτσουρεμένο άκρο. Οι άλλες επιλογές είναι στρογγυλή (χρησιμοποιεί ένα στρογγυλό τέλος, με το κέντρο του κύκλου στο τελικό σημείο) ή τετράγωνη (χρησιμοποιεί ένα τετραγωνισμένο τέλος, με το κέντρο του τετραγώνου στο τελικό σημείο). Αυτή η ρύθμιση ορίζεται χρησιμοποιώντας τη συνάρτηση <methodname>Cairo::Context::set_line_cap()</methodname>.Τεχνοτροπίες γραμμήςΑποθήκευση λιστώνΑποθήκευση λίστας (ListStore), για γραμμέςΦόρτωση του αρχείου .gladeΑναζήτηση στοιχείων στον κατάλογο των πρόσφατων αρχείωνΠολλά άτομα χρειάζονται να υλοποιήσουν δεξιό πάτημα σε μενού περιεχομένων για την <classname>TreeView</classname>, έτσι θα εξηγήσουμε πώς να το κάνετε αυτό εδώ για να σας εξοικονομήσουμε κάποιο χρόνο. Πέρα από ένα ή δύο σημεία, είναι παρεμφερές με το κανονικό μενού περιεχομένων, όπως περιγράφηκε στο <link linkend="sec-menus-popup">κεφάλαιο μενού</link>.Κύριο μενούΚύριο παράδειγμα μενούΑρχεία Makefile.amΔιαχειριζόμενα γραφικά συστατικάΠολλές συναρτήσεις σχεδίασης Cairo έχουν μια παραλλαγή <methodname>_preserve()</methodname>. Κανονικά οι συναρτήσεις σχεδίασης όπως <methodname>clip()</methodname>, <methodname>fill()</methodname>, ή <methodname>stroke()</methodname> θα καθαρίσουν την τρέχουσα διαδρομή. Αν χρησιμοποιήσετε την παραλλαγή <methodname>_preserve()</methodname>, η τρέχουσα διαδρομή θα διατηρηθεί, έτσι ώστε να μπορείτε να χρησιμοποιήσετε την ίδια διαδρομή με την επόμενη συνάρτηση σχεδίασης.Πολλά πακέτα εργαλείων GUI απαιτούν την ακριβή τοποθέτηση γραφικών συστατικών σε ένα παράθυρο, χρησιμοποιώντας απόλυτη τοποθέτηση, χρησιμοποιώντας συχνά έναν οπτικό επεξεργαστή. Αυτό οδηγεί σε πολλά προβλήματα:Σημειώνοντας συμβολοσειρές για μετάφρασηMarkoΣημάδιαΜπορεί ο χρήστης να μην πρέπει να μπορεί να επιλέξει κάθε στοιχείο στη λίστα ή δένδρο σας. Για παράδειγμα, στο gtk-demo, μπορείτε να επιλέξετε μια παρουσίαση για να δείτε τον πηγαίο κώδικα, αλλά δεν έχει νόημα να επιλέξετε μια κατηγορία παρουσίασης.Μπορούν να χρησιμοποιηθούν στιγμιότυπα μελών, απλοποιώντας τη διαχείριση μνήμης. Όλα τα γραφικά συστατικά GTK+ C αντιμετωπίζονται με τη χρήση δεικτών.Ως κωδικοποιητής C++, ξέρετε ότι οι δείκτες πρέπει να αποφεύγονται, όπου είναι δυνατό.Διαχείριση μνήμηςΜενού και ΕργαλειοθήκεςΔιάλογος μηνύματος (MessageDialog)Μακροεντολές μεθόδουΜέθοδοιMicrosoft WindowsΠοικίλα γραφικά συστατικάΑνάμειξη APIs C και C++Στήλες προτύπουModelColumns()
{ add(m_col_id); add(m_col_name); }

  Gtk::TreeModelColumn&lt;int&gt; m_col_id;
  Gtk::TreeModelColumn&lt;Glib::ustring&gt; m_col_name;
};

ModelColumns m_columns;Τροποποίηση αρχείων δόμησηςΤροποποίηση του καταλόγου των πρόσφατων αρχείωνΕποπτεία εισόδου/εξόδουΠερισσότερες πληροφορίες για το τι βρίσκεται πίσω από τη διεργασία διεθνοποίησης και τοπικοποίησης παρουσιάζεται και επιδεικνύεται στο: <placeholder-1/>Περισσότερες από μια στήλη προτύπου ανά στήλη προβολήςΟι περισσότερες εφαρμογές θα έχουν μόνο μια <classname>Window</classname>, ή μόνο ένα κύριο παράθυρο. Αυτές οι εφαρμογές μπορούν να χρησιμοποιήσουν την υπερφόρτωση <methodname>Gtk::Application::run(Gtk::Window&amp;)</methodname>. Εμφανίζει το παράθυρο και επιστρέφει όταν το παράθυρο έχει κρυφτεί. Αυτό μπορεί να συμβεί όταν ο χρήστης κλείνει το παράθυρο, ή όταν ο κώδικάς σας αποφασίζει να <methodname>hide()</methodname> το παράθυρο. Μπορείτε να αποτρέψετε τον χρήστη από το κλείσιμο του παραθύρου (για παράδειγμα, αν υπάρχουν αναποθήκευτες αλλαγές) αντικαθιστώντας την <methodname>Gtk::Window::on_delete_event()</methodname>.Τα περισσότερα προσαρμοσμένα γραφικά συστατικά χρειάζονται τη δικιά τους <classname>Gdk::Window</classname> για να σχεδιαστούν. Έπειτα μπορείτε να καλείτε την <methodname>Gtk::Widget::set_has_window(true)</methodname> στον κατασκευαστή σας. (Αυτή είναι η προεπιλεγμένη τιμή.) Αν δεν καλέσετε την <methodname>set_has_window(false)</methodname>, πρέπει να αντικαταστήσετε την <methodname>on_realize()</methodname> και να καλέσετε τις <methodname>Gtk::Widget::set_realized()</methodname> και <methodname>Gtk::Widget::set_window()</methodname> από εκεί.Οι περισσότεροι διάλογοι σε αυτό το κεφάλαιο είναι αναγκαστικοί, παγώνουν την υπόλοιπη εφαρμογή ενώ εμφανίζονται. Είναι επίσης δυνατή η δημιουργία μη αναγκαστικού διαλόγου, που δεν παγώνει άλλα παράθυρα στην εφαρμογή. Το παρακάτω παράδειγμα εμφανίζει μία μη αναγκαστική <classname>AboutDialog</classname>. Αυτός δεν είναι ίσως το είδος του διαλόγου που θα κάνατε κανονικά μη αναγκαστικό, αλλά οι μη αναγκαστικοί διάλογοι μπορεί να είναι χρήσιμοι σε άλλες περιπτώσεις. Π.χ. ο διάλογος αναζήτησης και αντικατάστασης της <application>gedit</application> είναι μη αναγκαστικός.Τα περισσότερα από τα παραδείγματά μας χρησιμοποιούν αυτήν την τεχνική.Τα περισσότερα από τα κεφάλαια σε αυτό το βιβλίο πραγματεύονται ειδικά γραφικά συστατικά. Δείτε την ενότητα <link linkend="chapter-container-widgets">Γραφικά συστατικά περιέκτη</link> για περισσότερες λεπτομέρειες για την προσθήκη γραφικών συστατικών σε γραφικά συστατικά περιέκτη.Οι περισσότερες από τις χρήσιμες μεθόδους μέλους για αυτήν την κλάση είναι στην πραγματικότητα στη βασική κλάση <classname>Gtk::FileChooser</classname>.Οι περισσότερες συσκευασίες χρησιμοποιούν πλαίσια (boxes) όπως στο παραπάνω παράδειγμα. Αυτά είναι αόρατοι περιέκτες στους οποίους μπορούμε να συσκευάσουμε τα γραφικά συστατικά μας. Όταν συσκευάζονται γραφικά συστατικά σε ένα οριζόντιο πλαίσιο, τα αντικείμενα εισάγονται οριζόντια από αριστερά προς τα δεξιά ή δεξιά προς τα αριστερά ανάλογα με το αν χρησιμοποιείται <methodname>pack_start()</methodname> ή <methodname>pack_end()</methodname>. Σε ένα κάθετο πλαίσιο, τα γραφικά συστατικά συσκευάζονται από πάνω προς τα κάτω ή αντίστροφα. Μπορεί να χρησιμοποιήσετε οποιοδήποτε συνδυασμό πλαισίων μέσα ή δίπλα σε άλλα πλαίσια για τη δημιουργία της επιθυμητής επίδρασης.ΜετακίνησηΠολυνηματικά προγράμματαΠολυνηματικά προγράμματαΓραφικά συστατικά πολλαπλών στοιχείωνΤα γραφικά συστατικά πολλαπλών στοιχείων κληρονομούν από την <classname>Gtk::Container</classname>; ακριβώς όπως με την <classname>Gtk::Bin</classname>, χρησιμοποιείτε τις μεθόδους <methodname>add()</methodname> και <methodname>remove()</methodname> για την πρόσθεση και αφαίρεση περιεχόμενων γραφικών συστατικών. Αντίθετα με την <methodname>Gtk::Bin::remove()</methodname>, όμως, η μέθοδος <methodname>remove()</methodname> για την <classname>Gtk::Container</classname> παίρνει ένα όρισμα, ορίζοντας ποιο γραφικό συστατικό θα αφαιρεθεί.MurrayMurray CummingΈπειτα, καλούμε τη μέθοδο <methodname>set_border_width()</methodname> του παραθύρου. Αυτό ρυθμίζει τον χώρο μεταξύ των πλευρών του παραθύρου και του γραφικού συστατικού που περιέχει.Έπειτα, κάνουμε ένα αντικείμενο της κλάσης μας <classname>HelloWorld</classname>, του οποίου ο κατασκευαστής δεν παίρνει ορίσματα, αλλά δεν είναι ορατός ακόμα. Όταν καλούμε <methodname>Gtk::Application::run()</methodname>, δίνοντας το στο παράθυρο helloworld, εμφανίζει το παράθυρο και ξεκινά την <application>gtkmm</application><emphasis>βρόχος συμβάντος</emphasis>. Κατά τη διάρκεια του βρόχου συμβάντος της <application>gtkmm</application> αδρανεί, περιμένοντας για ενέργειες από τον χρήστη και απαντώντας κατάλληλα. Όταν ο χρήστης κλείνει το παράθυρο, η run() θα επιστρέψει, προκαλώντας την τελική γραμμή της συνάρτησής μας main() να εκτελεστεί. Η εφαρμογή στη συνέχεια θα τελειώσει.Κατόπιν πρέπει να προσαρμοστούμε στα ποικίλα αρχεία <filename>Makefile.am</filename>: <placeholder-1/>Έπειτα θα πρέπει να δημιουργήσετε μια <classname>UIManager</classname> και να προσθέσετε την <classname>ActionGroup</classname> στην <classname>UIManager</classname> με την <methodname>insert_action_group()</methodname>. Σε αυτό το σημείο είναι επίσης καλή ιδέα να πείτε στο γονικό παράθυρο να απαντήσει στις καθορισμένες συντομεύσεις πληκτρολογίου, χρησιμοποιώντας <methodname>add_accel_group()</methodname>.Κατόπιν, χρησιμοποιούμε τη μέθοδο <methodname>add()</methodname> του παραθύρου για να βάλουμε στο παράθυρο <literal>m_button</literal>. (η <methodname>add()</methodname> έρχεται από το <classname>Gtk::Container</classname>, που περιγράφεται στο κεφάλαιο των γραφικών συστατικών περιέκτη.) Η μέθοδος <methodname>add()</methodname> βάζει το γραφικό συστατικό στο παράθυρο, αλλά δεν εμφανίζει το γραφικό συστατικό. Τα γραφικά συστατικά της <application>gtkmm</application> είναι πάντα αόρατα, όταν τα δημιουργείτε - για την εμφάνισή τους, πρέπει να καλέσετε τη μέθοδό τους <methodname>show()</methodname>, που είναι αυτό που κάνουμε στην επόμενη γραμμή.Nicolai M. Josuttis, "The C++ Standard Library" - section 4.2Μη αναγκαστικό περί του διαλόγου (AboutDialog)Κανονική διαχείριση μνήμης C++Σημειώστε επίσης ότι όλα τα γραφικά συστατικά δέχονται όλα τα συμβάντα Χ από προεπιλογή. Για να δεχτείτε πρόσθετα συμβάντα Χ, μπορείτε να χρησιμοποιήσετε τη <methodname>Gtk::Widget::set_events()</methodname> πριν την εμφάνιση του γραφικού συστατικού, ή την <methodname>Gtk::Widget::add_events()</methodname> μετά την εμφάνιση του γραφικού συστατικού. Όμως, μερικά γραφικά συστατικά πρέπει πρώτα να τοποθετηθούν μέσα σε ένα γραφικό συστατικό <classname>EventBox</classname>. Δείτε το κεφάλαιο <link linkend="chapter-widgets-without-xwindows">Γραφικά συστατικά χωρίς παράθυρα X</link>.Σημειώστε ότι το UTF-8 δεν είναι συμβατό με κωδικοποιήσεις 8 δυαδικών όπως το ISO-8859-1. Για παράδειγμα, τα γερμανικά umlauts δεν είναι στην περιοχή ASCII και χρειάζεται περισσότερο από 1 ψηφιολέξη στην κωδικοποίηση UTF-8. Αν ο κώδικας σας περιέχει κυριολεκτικές συμβολοσειρές 8 δυαδικών, πρέπει να τις μετατρέψετε σε UTF-8 (π.χ. ο βαυαρικός χαιρετισμός "Grüß Gott" πρέπει να είναι "Gr\xC3\xBC\xC3\x9F Gott").Σημειώστε ότι τα αρχεία που τελειώνουν σε <filename>.in</filename> θα χρησιμοποιηθούν για τη δημιουργία αρχείων με το ίδιο όνομα, αλλά χωρίς το επίθεμα <filename>.in</filename>, αντικαθιστώντας μερικές μεταβλητές με τις ενεργές τιμές κατά τη διάρκεια του σταδίου διαμόρφωσης.Σημειώστε ότι αν αναφέρετε πρόσθετα αρθρώματα πέρα από το gtkmm-3.0, θα πρέπει να χωρίζονται από διαστήματα, όχι κόμματα.Σημειώστε ότι σε αυτήν την περίπτωση, έχουμε εκφράσει σχεδόν καθετί ως προς το ύψος και το πλάτος του παραθύρου, συμπεριλαμβάνοντας το πλάτος των γραμμών. Λόγω αυτού, όταν αυξομειώνετε το παράθυρο, καθετί κλιμακώνεται με το παράθυρο. Επίσης, σημειώστε ότι υπάρχουν τρεις ενότητες σχεδίασης στη συνάρτηση και καθεμιά συσκευάζεται με ένα ζεύγος <methodname>save()</methodname>/<methodname>restore()</methodname>, έτσι ώστε να είμαστε πίσω σε μια γνωστή κατάσταση μετά από κάθε σχεδίαση.Σημειώστε ότι οι περισσότερες ομάδες γλώσσας αποτελούνται μόνο από 1-3 άτομα, έτσι αν το πρόγραμμά σας περιέχει πολλές συμβολοσειρές, μπορεί να κρατήσει κάμποσο πριν οποιοσδήποτε έχει τον χρόνο να το κοιτάξει. Επίσης, οι περισσότεροι μεταφραστές δεν θέλουν να σπαταλούν τον χρόνο τους (η μετάφραση είναι μια πολύ χρονοβόρα εργασία), έτσι δεν αξιολογούν το έργο σας ως πραγματικά σοβαρό (με την έννοια ότι είναι βελτιωμένο και συντηρούμενο) μπορεί να αποφασίσουν να διαθέσουν τον χρόνο τους σε κάποιο άλλο έργο.Σημειώστε ότι το στιγμιότυπο (όπως m_Columns εδώ) πρέπει συνήθως να μην είναι στατικό, επειδή χρειάζεται συχνά να δημιουργηθεί αφού η glibmm έχει δημιουργηθεί.Σημειώστε ότι εκεί ορίζουμε τα ονόματα των ενεργειών, όπως θα φαίνονται στους χρήστες σε μενού και εργαλειοθήκες. Συνεπώς, εκεί θα πρέπει να κάνετε μεταφράσιμες τις συμβολοσειρές, βάζοντας τες μέσα στην μακροεντολή _().Σημειώστε ότι για τη δόμηση της <application>gtkmm</application> από το git, θα χρειαστείτε συχνά να δομήσετε όλες τις εξαρτήσεις από το git επίσης. Η <application>jhbuild</application> διευκολύνει από ότι κανονικά θα γινόταν, αλλά θα πάρει κάμποσο για να δομήσετε και να τις εγκαταστήσετε όλες. Θα αντιμετωπίσετε προφανώς προβλήματα δόμησης, αν και αυτά συνήθως διορθώνονται γρήγορα, αν τα αναφέρετε.Σημειώστε ότι δεν περάσαμε έναν δείκτη στην <methodname>on_button_clicked()</methodname> άμεσα από τη μέθοδο <methodname>connect()</methodname> του σήματος. Αντίθετα, καλούμε <function>sigc::ptr_fun()</function> και περνάμε το αποτέλεσμα στην <methodname>connect()</methodname>.Σημειώστε ότι δεν μπορείτε απλά να βάλετε <placeholder-1/>, επειδή η ομάδα τροποποιείται από τη <methodname>set_group()</methodname> και συνεπώς δεν είναι σταθερή.Σημειώστε ότι πρέπει να ορίσετε ενέργειες για υπομενού καθώς και για στοιχεία μενού.Σημειώστε ότι, λόγω του συστήματος θεμάτων του GTK+, η εμφάνιση αυτών των γραφικών συστατικών θα ποικίλει. Στην περίπτωση των πλαισίων ελέγχου και ραδιοπλήκτρων, μπορεί να ποικίλουν σημαντικά.Σημειώστε, όμως, ότι η TreeView θα δώσει επαναλήπτες στο ταξινομημένο πρότυπο. Πρέπει να τους μετατρέψετε σε επαναλήπτες στο υποκείμενο θυγατρικό πρότυπο για να εκτελέσετε ενέργειες σε αυτό το πρότυπο. Για παράδειγμα:ΣημειωματάριοΣημειώστε ότι η τιμή επιστροφής είναι του τύπου <classname>sigc::signal&lt;void,int&gt;::iterator</classname>. Αυτό μπορεί να είναι έμμεσα αλλαγμένο σε <classname>sigc::connection</classname> που με τη σειρά της μπορεί να χρησιμοποιηθεί για τον έλεγχο της σύνδεσης. Κρατώντας ένα αντικείμενο σύνδεσης μπορείτε να αποσυνδέσετε τον συσχετισμένο χειριστή σήματος χρησιμοποιώντας τη μέθοδο <methodname>sigc::connection::disconnect()</methodname>.Σημειώστε ότι παρείχαμε την <command>gmmproc</command> με τη διαδρομή στα αρχεία μετατροπής .m4, τη διαδρομή στο αρχείο .defs, το όνομα ενός αρχείου .hg, τον πηγαίο κατάλογο και τον κατάλογο προορισμού.Σημειώστε ότι έχουμε χρησιμοποιήσει μια πρόταση αρχικοποίησης για να δώσουμε στο αντικείμενο <literal>m_button</literal> την ετικέτα "Hello World".Σημειώστε, ότι μετά την ακύρωση ενός συμβάντος, καμιά άλλη συνάρτηση δεν θα κληθεί (ακόμα κι αν είναι από το ίδιο γραφικό συστατικό).Τώρα ας κοιτάξουμε στη συνάρτηση <function>main()</function> του προγράμματός μας. Να τη, χωρίς σχόλια:Τώρα ας κοιτάξουμε στη σύνδεση ξανά:Τώρα, ας δείτε τι συμβαίνει όταν μια εξαίρεση συμβαίνει από έναν χειριστή σήματος. Ιδού ο πηγαίος κώδικας. <placeholder-1/>Τώρα, ας ρίξουμε μια ματιά στον κώδικα που εκτελεί την ενεργή σχεδίαση. Η πρώτη ενότητα της <methodname>on_draw()</methodname> πρέπει να είναι αρκετά οικεία μέχρι τώρα. Αυτό το παράδειγμα κλιμακώνει πάλι το σύστημα συντεταγμένων για να είναι μια τετράγωνη μονάδα, έτσι ώστε να είναι ευκολότερη η σχεδίαση του ρολογιού ως ποσοστού του μεγέθους του παραθύρου, έτσι ώστε να κλιμακώσει αυτόματα όταν το μέγεθος του παραθύρου προσαρμόζεται. Επιπλέον, το σύστημα συντεταγμένων κλιμακώνεται πάνω και κάτω έτσι ώστε η συντεταγμένη (0, 0) να είναι ακριβώς στο κέντρο του παραθύρου.Τώρα που υπάρχει μια θέση να βάλετε τις μεταφράσεις σας, χρειάζεται να αρχικοποιήσετε τις <application>intltool</application> και <application>gettext</application>. Προσθέστε τον ακόλουθο κώδικα στην <literal>configure.ac</literal>, αντικαθιστώντας το 'programname' με το όνομα του προγράμματός σας:Τώρα που κατανοήσαμε τα βασικά της βιβλιοθήκης γραφικών του Cairo, είμαστε σχεδόν έτοιμοι να ξεκινήσουμε τη σχεδίαση. Θα αρχίσουμε με τα πιο απλά στοιχεία σχεδίασης: την ευθεία γραμμή. Αλλά πρώτα χρειάζεται να ξέρετε λίγα για το σύστημα συντεταγμένων του Cairo. Η αρχή του συστήματος συντεταγμένων του Cairo βρίσκεται στην πάνω αριστερή γωνία του παραθύρου με θετικές τιμές x στα δεξιά και θετικές τιμές y προς τα κάτω. <placeholder-1/>Τώρα, που έχουμε καλύψει τα βασικά της σχεδίασης με Cairo, ας δοκιμάσουμε να τα βάλουμε όλα μαζί και να δημιουργήσουμε μια απλή εφαρμογή που πράγματι κάνει κάτι. Το παρακάτω παράδειγμα χρησιμοποιεί Cairo για τη δημιουργία ενός προσαρμοσμένου γραφικού συστατικού <classname>Clock</classname>. Το ρολόι έχει ένα δευτερολεπτοδείκτη, έναν λεπτοδείκτη και έναν ωροδείκτη και ενημερώνει τον εαυτόν του κάθε δευτερόλεπτο.Τώρα που έχετε δει σήματα και χειριστές σήματος στην <application>gtkmm</application>, μπορεί να σας αρέσει να χρησιμοποιήσετε την ίδια τεχνική για να επιτρέψετε την αλληλεπίδραση μεταξύ των δικών σας κλάσεων. Αυτό είναι στην πραγματικότητα πολύ απλό χρησιμοποιώντας την βιβλιοθήκη <application>libsigc++</application> άμεσα.Τώρα επεξεργαζόμαστε τα αρχεία για να προσαρμόσουμε στις ανάγκες μας. Μπορείτε να προτιμήσετε τη χρήση ενός βοηθήματος πολλαπλού αρχείου αναζήτησης-αντικατάστασης για αυτό, όπως <command>regexxer</command>. Σημειώστε ότι σχεδόν όλα τα παρεχόμενα αρχεία με το πηγαίο δένδρο σκελετού περιέχουν κείμενο δεσμευτικού θέσης. Έτσι, οι αντικαταστάσεις πρέπει να εκτελεστούν καθολικά και να μην περιοριστούν στα αρχεία Automake και Autoconf.Εντάξει, αυτό είναι ωραίο, αλλά τι θα συμβεί αν θελήσετε να δημιουργήσετε τους δικούς σας χειριστές για να απαντούν όταν ο χρήστης ρυθμίζει ένα γραφικό συστατικό <classname>Range</classname> ή μια <classname>SpinButton</classname>. Για να προσπελάσετε την τιμή μιας <classname>Gtk::Adjustment</classname>, μπορείτε να χρησιμοποιήσετε τις μεθόδους <methodname>get_value()</methodname> και <methodname>set_value()</methodname>:Αντικείμενα και συναρτήσεις.Αντικείμενα όπως <classname>Gdk::Pixbuf</classname> μπορούν μόνο να δημιουργηθούν με μια συνάρτηση <methodname>create()</methodname>. Για παράδειγμα, <placeholder-1/>Τα αντικείμενα χρησιμοποιούνται μέσα από <classname>RefPtr</classname>: Περνάνε την <classname>RefPtr</classname> ως μια αναφορά σταθεράς. Για παράδειγμα, <code>const Glib::RefPtr&lt;Gtk::FileFilter&gt;&amp; filter</code>.Ενίοτε μπορεί να θέλετε να κάνετε ένα γραφικό συστατικό <classname>Entry</classname> μόνο για ανάγνωση. Αυτό μπορεί να γίνει περνώντας το <literal>false</literal> στη μέθοδο <methodname>set_editable()</methodname>.Φυσικά αυτό σημαίνει ότι μπορείτε να αποθηκεύσετε τις <classname>RefPtr</classname>s σε τυπικούς περιέκτες, όπως <classname>std::vector</classname> ή <classname>std::list</classname>.Φυσικά, ένας περιέκτης ανωτάτου επιπέδου δεν θα προστεθεί σε άλλον περιέκτη. Ο προγραμματιστής είναι υπεύθυνος για την καταστροφή του περιέκτη ανωτάτου επιπέδου χρησιμοποιώντας μία από τις παραδοσιακές τεχνικές της C++. Για παράδειγμα, το παράθυρο ανωτάτου επιπέδου σας μπορεί να είναι απλά ένα στιγμιότυπο στη συνάρτησή σας <function>main()</function>.Συχνά με τις μεθόδους συσκευασίας, είναι επιθυμητό να αποθηκεύσετε την επιστροφή της συνάρτησης C σε αυτό που λέγεται μια παράμετρος εξόδου. Σε αυτήν την περίπτωση, η μέθοδος C++ επιστρέφει τον <type>void</type>, αλλά μια παράμετρος εξόδου στην οποία αποθηκεύεται η τιμή της συνάρτησης C συμπεριλαμβάνεται στη λίστα ορισμάτων της μεθόδου C++. Η gmmproc επιτρέπει τέτοια λειτουργικότητα, αλλά οι κατάλληλες μακροεντολές αρχικοποίησης πρέπει να συμπεριληφθούν για να πουν στην gmmproc πώς να αρχικοποιήσετε την παράμετρο C++ από την επιστροφή της συνάρτησης C.OleΣτο Γιούνιξ, ο προεπιλεγμένος χειριστής προεπισκόπησης χρησιμοποιεί ένα εξωτερικό πρόγραμμα προβολής. Στα Windows, ο εγγενής διάλογος προεπισκόπησης θα εμφανιστεί. Αν είναι απαραίτητο, μπορείτε να αντικαταστήσετε αυτήν τη συμπεριφορά και να δώσετε έναν προσαρμοσμένο διάλογο προεπισκόπησης. Δείτε το παράδειγμα που βρίσκεται στο /examples/book/printing/advanced.Αφού έχετε δημιουργήσει το λογισμικό σας, θα χρειαστείτε να εκτελέσετε το πρόγραμμά σας μέσα σε περιβάλλον jhbuild επίσης. Για να το κάνετε αυτό, μπορείτε να χρησιμοποιήσετε πάλι την εντολή <command>jhbuild shell</command> για να ξεκινήσετε ένα νέο φλοιό με το εγκατεστημένο περιβάλλον <application>jhbuild</application>. Εναλλακτικά, μπορείτε να εκτελέσετε μια κι έξω την εντολή στο περιβάλλον <application>jhbuild</application> χρησιμοποιώντας την ακόλουθη εντολή: <command>jhbuild run command-name</command>. Σε αυτήν την περίπτωση, η εντολή θα εκτελεστεί με ορισμένες τις σωστές μεταβλητές περιβάλλοντος, αλλά θα επιστρέψει στο προηγούμενο περιβάλλον σας αφού εξέλθει το πρόγραμμα.Αφού έχετε ρυθμίσει την <application>jhbuild</application> όπως περιγράφτηκε παραπάνω, η δόμηση της <application>gtkmm</application> πρέπει να είναι σχετικά απλή. Την πρώτη φορά που εκτελείτε, την <application>jhbuild</application>, θα πρέπει να εκτελέσετε την ακόλουθη σειρά εντολών για να εξασφαλίσετε ότι η <application>jhbuild</application> έχει τα απαιτούμενα εργαλεία και να επιβεβαιώσετε ότι ρυθμίστηκε σωστά: <screen>$ jhbuild bootstrap
$ jhbuild sanitycheck</screen>Ένα από τα πλεονεκτήματα του UTF-8 είναι ότι δεν χρειάζεστε να το χρησιμοποιήσετε εκτός και το θέλετε, έτσι δεν χρειάζεστε να τροποποιήσετε όλο τον κώδικά σας μονομιάς. Η <classname>std::string</classname> θα δουλέψει ακόμα για συμβολοσειρές ASCII 7 δυαδικών ψηφίων. Αλλά, όταν δοκιμάσετε να τοπικοποιήσετε την εφαρμογή σας για γλώσσες όπως κινέζικα, για παράδειγμα, θα αρχίσετε να βλέπετε περίεργα σφάλματα και πιθανές καταρρεύσεις. Τότε, αυτό που χρειάζεται να κάνετε είναι να αρχίσετε να χρησιμοποιείτε τη <classname>Glib::ustring</classname> στη θέση του.Ένα από τα μεγάλα πλεονεκτήματα της <application>gtkmm</application> είναι ότι είναι διαλειτουργική. Τα προγράμματα <application>gtkmm</application> που είναι γραμμένα σε άλλα λειτουργικά όπως GNU/Λίνουξ μπορούν γενικά να μεταφερθούν στα Windows (και αντίστροφα) με λίγες τροποποιήσεις στην πηγή.Openismus έχει περισσότερη <ulink url="http://www.openismus.com/documents/linux/automake/automake.shtml">βασική βοήθεια με automake και autoconf</ulink>.Προαιρετική επεξεργασία παραμέτρουΉ μπορείτε να ορίσετε την ετικέτα, όταν εισάγετε πρώτα το κείμενο: <placeholder-1/>Άλλες μακροεντολέςΆλλες μακροεντολές, όπως <function>_WRAP_METHOD()</function> και <function>_WRAP_SIGNAL()</function> μπορούν να χρησιμοποιηθούν μόνο μετά από μια κλήση στη μακροεντολή <function>_CLASS_*</function>.Πέρα από το όνομα του σήματος (<literal>focus</literal>), δύο πράγματα είναι σημαντικά να σημειώσετε εδώ: ο αριθμός που ακολουθεί τη λέξη <classname>SignalProxy</classname> στην αρχή (1, σε αυτήν την περίπτωση) και οι τύποι στη λίστα (<type>bool</type> και <type>Gtk::DirectionType</type>). Ο αριθμός δείχνει πόσα ορίσματα πρέπει να έχει ο χειριστής σήματος· ο πρώτος τύπος, <type>bool</type>, είναι ο τύπος που ο χειριστής σήματος πρέπει να επιστρέψει· και ο επόμενος τύπος, <type>Gtk::DirectionType</type>, είναι ο τύπος του πρώτου αυτού του σήματος και μόνο, όρισμα. Κοιτώντας στην τεκμηρίωση αναφοράς, μπορείτε να δείτε τα ονόματα των ορισμάτων επίσης.Όλα τα παραδείγματά μας τείνουν να έχουν την ίδια δομή. Ακολουθούν αυτά τα βήματα για τη χρήση μιας <classname>Widget</classname>:Επεξεργασία παραμέτρου εξόδουΑντικατάσταση προεπιλεγμένων χειριστών σημάτωνΕπισκόπησηPKG_CHECK_MODULES([MYAPP], [gtkmm-3.0 &gt;= 3.8.0])Συσκευάστε το γραφικό συστατικό σε έναν περιέκτη χρησιμοποιώντας την κατάλληλη κλήση, π.χ. <methodname>Gtk::Container::add()</methodname> ή <methodname>pack_start()</methodname>.ΠακετάρισμαΔιαμόρφωση σελίδαςΜε φατνώματα (Paned)Τα φατνώματα (Panes) διαιρούν ένα γραφικό συστατικό σε δύο μισά, που χωρίζονται από ένα μετακινήσιμο χώρισμα. Τα δύο μισά (φατνώματα) μπορούν να προσανατολιστούν ή οριζόντια (πλάι-πλάι) ή κάθετα (το ένα πάνω από το άλλο).PangoΑναδιάταξη παραμέτρουΜέρη του κεφαλαίου "Διεθνοποίηση".Μέρη της ενημέρωσης από gtkmm 2 σε gtkmm 3.ΕπικόλλησηPedroΕπιλογές συσκευασίας ανά θυγατρικόΕπιλογές συσκευασίας ανά περιέκτηΕπιτρέπεται η αντιγραφή, η διανομή και/ή τροποποίηση αυτού του εγγράφου υπό τους όρους της Ελεύθερης άδειας τεκμηρίωσης GNU, έκδοσης 1.2 ή σε οποιαδήποτε μεταγενέστερη, όπως αυτή δημοσιεύεται από το Ίδρυμα ελεύθερου λογισμικού· χωρίς αμετάβλητα τμήματα, χωρίς κείμενα εξωφύλλου ή οπισθόφυλλου. Μπορείτε να λάβετε ένα αντίγραφο της Ελεύθερης άδειας τεκμηρίωσης GNU από το Ίδρυμα ελεύθερου λογισμικού επισκεπτόμενοι τον ιστότοπό τους ή γράφοντας στο: Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.ΠαγίδεςΠαρακαλούμε σημειώστε ότι όταν αναδιατάσσονται παράμετροι για μια υπογραφή μεθόδου <function>_WRAP_SIGNAL()</function>, τα ονόματα παραμέτρου C πρέπει να είναι πάντα <literal>p0</literal>, <literal>p1</literal>, κλπ., επειδή το εργαλείο <filename>generate_extra_defs</filename> χρησιμοποιεί αυτά τα ονόματα παραμέτρων ανεξάρτητα από το ποια μπορεί να είναι τα ονόματα παραμέτρου της API της C. Έτσι είναι γραμμένο προς το παρόν το βοήθημα.Παρακαλούμε, δείτε <ulink url="http://live.gnome.org/gtkmm/MSWindows/BuildingGtkmm">http://live.gnome.org/gtkmm/MSWindows/BuildingGtkmm</ulink> για οδηγίες δόμησης της gtkmm σε Windows.Δέκτες (Plugs)Δέκτες και δότες (Plugs and Sockets)Παράδειγμα δεκτών και δοτών (Plugs and Sockets)Αναδυόμενο μενού περιεχομένωνΑναδυόμενο μενούΑναδυόμενο παράδειγμα μενούΑναδυόμενα μενούΠροκατασκευασμένα πακέταΠροετοιμασία του έργου σαςΑρκετά συναρπαστικό; Ας εξετάσουμε τον κώδικα. Πρώτα, την κλάση <classname>HelloWorld</classname>:Αποτρέποντας την επιλογή γραμμήςΠροεπισκόπησηΛειτουργία εκτύπωσης (PrintOperation)ΕκτύπωσηΕκτύπωση - ΑπλήΠροφανώς ο πιο συνηθισμένος τρόπος δημιουργίας <classname>Gdk::Pixbuf</classname>s είναι η χρήση <methodname>Gdk::Pixbuf::create_from_file()</methodname>, που μπορεί να διαβάσει ένα αρχείο εικόνας, όπως ένα αρχείο png σε ένα pixbuf έτοιμο για απόδοση.Προβλήματα στη API της C.Προγραμματισμός με <application>gtkmm</application> 3Οι γραμμές προόδου χρησιμοποιούνται για την εμφάνιση της κατάστασης της συνεχιζόμενης λειτουργίας. Για παράδειγμα, μια <classname>ProgressBar</classname> μπορεί να εμφανίσει πόση εργασία έχει ολοκληρωθεί.Γραμμή προόδουΚουμπιά πίεσηςΒάζει τον δημιουργούμενο κώδικα σε ομάδες #ifdef.Βάζει τον δημιουργούμενο κώδικα σε ομάδες #ifdef. Το κείμενο για τα παρωχημένα μπορεί να οριστεί ως προαιρετική παράμετρος.ΡαδιοπλήκτραΡαδιοπλήκτροΓραφικά συστατικά περιοχήςΑναφορικά με την αντικατάσταση χειριστών σημάτων: Μπορείτε να το κάνετε στον κόσμο της άμεσης C της GTK+ επίσης· για υτό είναι το σύστημα αντικειμένου του GTK. Αλλά στην GTK+, πρέπει να περάσετε μέσα από κάποιες περίπλοκες διαδικασίες για να πάρετε αντικειμενοστραφή χαρακτηριστικά όπως κληρονομικότητα και υπερφόρτωση. Στην C++, είναι απλό, αφού αυτά τα χαρακτηριστικά υποστηρίζονται στην ίδια τη γλώσσα· μπορείτε να επιτρέψετε στον μεταγλωττιστή να κάνει τη βρόμικη δουλειά.Οι πρόσφατες εκδόσεις της <application>gtkmm</application> είναι πακεταρισμένες από σχεδόν κάθε μεγάλη διανομή Λίνουξ αυτές τις ημέρες. Έτσι, αν χρησιμοποιείτε Λίνουξ, μπορείτε προφανώς να ξεκινήσετε με τη <application>gtkmm</application> εγκαθιστώντας το πακέτο από το επίσημο αποθετήριο για τη διανομή σας. Οι διανομές που περιλαμβάνουν τη <application>gtkmm</application> στα αποθετήριά τους περιλαμβάνουν Ντέμπιαν, Ουμπούντου, Ρέντ Χατ, Φεντόρα, Μαντρίβα, Σούσε και πολλές άλλες.Επιλογή προσφάτων (RecentChooser)Πρόσφατος διαχειριστής (RecentManager)Πρόσφατα χρησιμοποιημένα έγγραφαΣυνιστώμενες τεχνικέςΑναφοράΝα θυμάστε ότι σε ένα λειτουργικό σύστημα Γιούνιξ ή Λίνουξ θα χρειαστείτε προφανώς να είσαστε <literal>root</literal> (υπερχρήστης) για την εγκατάσταση λογισμικού. Η εντολή <command>su</command> ή <command>sudo</command> θα επιτρέψει να εισάγετε τον κωδικό πρόσβασης του <literal>root</literal> και να έχετε προσωρινά την κατάσταση <literal>root</literal>.Να θυμάστε ότι αυτά τα ονόματα είναι απλά αναγνωριστικά που χρησιμοποιούμε όταν δημιουργούμε τις ενέργειες. Δεν είναι το κείμενο που θα δει ο χρήστης στα μενού και τις εργαλειοθήκες. Δίνουμε αυτά τα αναγνώσιμα από άνθρωπο ονόματα όταν δημιουργούμε τις ενέργειες.Να θυμάστε ότι δεν δημιουργείτε ένα γραφικό συστατικό με τη <methodname>get_widget()</methodname>, απλά παίρνετε έναν δείκτη στο ήδη υπάρχον. Θα δεχτείτε πάντα έναν δείκτη στο ίδιο στιγμιότυπο, όταν καλείτε την <methodname>get_widget()</methodname> στην ίδια <classname>Gtk::Builder</classname>, με το ίδιο όνομα γραφικού συστατικού. Τα γραφικά συστατικά δημιουργούνται κατά τη διάρκεια της <methodname>Gtk::Builder::create_from_file()</methodname>.Απεικόνιση κειμένουΑναδιατάξιμες γραμμέςΠόροιΑπάντηση σε αλλαγέςΕπαναχρησιμοποίηση τεκμηρίωσης CRiederΘυγατρικά γραμμήΊδιες συμβολοσειρές, διαφορετική σημασιολογίαΚλιμάκωση γραφικών συστατικώνΓραφικά συστατικά γραμμής κύλισηςΤα κυλιόμενα παράθυρα έχουν <emphasis>πολιτικές γραμμής κύλισης</emphasis> που προσδιορίζουν αν οι <classname>Scrollbar</classname>s θα εμφανίζονται. Οι πολιτικές μπορούν να οριστούν με τη μέθοδο <methodname>set_policy()</methodname>. Η πολιτική μπορεί να είναι από τις <literal>Gtk::POLICY_AUTOMATIC</literal> ή <literal>Gtk::POLICY_ALWAYS</literal>. Το <literal>Gtk::POLICY_AUTOMATIC</literal> θα προκαλέσει στο κυλιόμενο παράθυρο να εμφανίζει τη γραμμή κύλισης μόνο αν το περιεχόμενο γραφικό συστατικό είναι μεγαλύτερο από την ορατή περιοχή. Το <literal>Gtk::POLICY_ALWAYS</literal> θα προκαλέσει στη γραμμή κύλισης να εμφανίζεται πάντα.Κυλιόμενο παράθυροΚύλισηΔεύτερο, ελέγξτε για σφάλμα και συνδεθείτε με το σήμα <literal>status_changed</literal>. Για παράδειγμα: <placeholder-1/>Ενότητα "Δημιουργία δομής" του κεφαλαίου "Συσκευασία βιβλιοθηκών C με gmmproc".Ενότητα στο Gtk::Πλέγμα.Δείτε <link linkend="sec-printing-example-simple">ένα παράδειγμα</link> πώς ακριβώς μπορεί να γίνει αυτό.Δείτε το κεφάλαιο <link linkend="chapter-draganddrop">Μεταφορά και απόθεση</link> για γενικές συμβουλές σχετικά με τη μεταφορά και απόθεση με gtkmm.Δείτε την ενότητα <link linkend="chapter-internationalization">διεθνοποίηση</link> για πληροφορίες σχετικές με την παροχή κυριολεκτικών συμβολοσειρών UTF-8.Δείτε το <link linkend="chapter-refptr">παράρτημα</link> για λεπτομερείς πληροφορίες σχετικά με την RefPtr.Δείτε την ενότητα <link linkend="sec-progressbar">Γραμμή προόδου</link> για ένα άλλο παράδειγμα που χρησιμοποιεί μια <classname>Alignment</classname>.Επιλέγοντας ποιοι τύποι C++ πρέπει να χρησιμοποιηθούν είναι επίσης σημαντικό όταν συσκευάζετε API της C. Αν και είναι συνήθως φανερό ποιοι τύποι C++ πρέπει να χρησιμοποιηθούν στη μέθοδο C++, ιδού μερικές υποδείξεις: <placeholder-1/>Ορίστε τα γνωρίσματα του γραφικού συστατικού. Αν το γραφικό συστατικό δεν έχει προεπιλεγμένο κατασκευαστή, τότε θα χρειαστείτε να αρχικοποιήσετε το γραφικό συστατικό στον κατάλογο αρχικοποίησης του κατασκευαστή της κλάσης περιέκτη.Ορίστε τον τίτλο της καρτέλας μέσα από την <methodname>PrintOperation::set_custom_tab_label()</methodname>, δημιουργήστε ένα νέο γραφικό συστατικό και επιστρέψτε την από τον χειριστή σήματος <literal>create_custom_widget</literal>. Θα θέλετε προφανώς αυτό να είναι ένα γραφικό συστατικό περιέκτη, συσκευασμένο με μερικά άλλα.Ορίζοντας ένα πρόθεμαΕγκατάσταση της jhbuildΟρισμός τιμώνΚοινόχρηστοι πόροιΠαρακάτω εμφανίζεται ένα απλό παράδειγμα χρήσης των κλάσεων <classname>RecentChooserDialog</classname> και <classname>RecentAction</classname> σε ένα πρόγραμμα. Αυτό το απλό πρόγραμμα έχει μια γραμμή μενού με ένα στοιχείο μενού <guimenuitem>Διάλογος πρόσφατων αρχείων</guimenuitem>. Όταν επιλέγετε αυτό το στοιχείο μενού, ένας διάλογος αναδύεται εμφανίζοντας τον κατάλογο των πρόσφατα χρησιμοποιημένων αρχείων.Αλληλουχία χειριστή σήματοςΣήματαΣήματα και ιδιότητες.Τα σήματα συνήθως έχουν δείκτες συνάρτησης στη δομή GTK, με μια αντίστοιχη τιμή απαρίθμησης και μια <function>g_signal_new()</function> στο αρχείο .c.ΑπλόΑπλό παράδειγμα καταχώρισηςΑπλό παράδειγμαΑπλό παράδειγμα διαλόγου επιλογής προσφάτων (RecentChooserDialog)Απλό παράδειγμα κειμένουΑπλή χρήσηΗ λειτουργία αντιγραφής-επικόλλησης απλού κειμένου παρέχεται ελεύθερα από γραφικά συστατικά όπως <classname>Gtk::Entry</classname> και <classname>Gtk::TextView</classname>, αλλά μπορεί να χρειαστείτε ειδικό κώδικα για να αντιμετωπίσετε τις δικές σας μορφές δεδομένων. Για παράδειγμα, ένα πρόγραμμα σχεδίασης μπορεί να χρειαστεί ειδικό κώδικα για να επιτρέψει την αντιγραφή και επικόλληση μέσα σε μια προβολή, ή μεταξύ εγγράφων.Αφού μια <classname>Plug</classname> είναι απλά ένας ειδικός τύπος μιας κλάσης <classname>Gtk::Window</classname>, μπορείτε να προσθέσετε περιέκτες ή γραφικά συστατικά σε αυτή όπως μπορείτε να κάνετε με οποιοδήποτε άλλο παράθυρο.Αφού τα η βιβλιοθήκη γραφικών Cairo γράφτηκε με υποστήριξη για πολλαπλούς προορισμούς εξόδου (το σύστημα παραθύρου Χ, εικόνες PNG, OpenGL, κλπ), υπάρχει μια διάκριση μεταξύ συντεταγμένων χώρου χρήστη και χώρου συσκευής. Η αντιστοίχιση μεταξύ αυτών των δύο συστημάτων συντεταγμένων προεπιλέγει σε αντιστοίχιση ένα προς ένα, έτσι ώστε οι ακέραιες τιμές να απεικονίζουν χοντρικά εικονοστοιχεία στην οθόνη, αλλά αυτή η ρύθμιση μπορεί να προσαρμοστεί, εάν θέλετε. Μερικές φορές, μπορεί να είναι χρήσιμο να κλιμακώσετε τις συντεταγμένες έτσι ώστε το πλήρες πλάτος και ύψος ενός παραθύρου να βρίσκεται από 0 μέχρι 1 (η 'τετράγωνη μονάδα') ή κάποια άλλη απεικόνιση που δουλεύει για την εφαρμογή σας. Αυτό μπορεί να γίνει με τη λειτουργία <methodname>Cairo::Context::scale()</methodname>.Αφού αυτό είναι πολύ παρόμοιο με τις παραπάνω μεθόδους αυτή η εξήγηση πρέπει να είναι αρκετή για την κατανόηση του τι συμβαίνει. Όμως, να ένα μικρό παράδειγμα:Μεμονωμένη ή πολλαπλή επιλογήΠεριέκτες μοναδικού στοιχείουΜέχρι τώρα σας έχουμε πει να εκτελείτε ενέργειες σε απάντηση των πατημάτων πλήκτρου και το παρόμοιο χειριζόμενοι σήματα. Αυτός είναι σίγουρα ένας καλός τρόπος να γίνονται τα πράγματα, αλλά δεν είναι ο μόνος τρόπος.Για να μπορεί ένας χρήστης να πατά σε μία κεφαλίδα στήλης <classname>TreeView</classname> για να ταξινομήσει τα περιεχόμενα της <classname>TreeView</classname>, καλέστε <methodname>Gtk::TreeView::Column::set_sort_column()</methodname>, παρέχοντας τη στήλη προτύπου στην οποία το πρότυπο πρέπει να ταξινομηθεί, όταν πατηθεί η κεφαλίδα. Για παράδειγμα:Για να μπορούν αυτές οι εφαρμογές να αντιδρούν στις αλλαγές, για παράδειγμα όταν ένας χρήστης μετακινεί μια γραμμή κύλισης, η <classname>Gtk::Adjustment</classname> έχει ένα σήμα <literal>value_changed</literal>. Μπορείτε έπειτα να χρησιμοποιήσετε τη μέθοδο <methodname>get_value()</methodname> για να βρείτε τη νέα τιμή.Για να μπορεί να αλληλεπιδράσει η <classname>Entry</classname> με την πτυσσόμενη λίστα επιλογών, πρέπει να ορίσετε ποιες στήλες του προτύπου σας είναι η στήλη κειμένου, με <methodname>set_entry_text_column()</methodname>. Για παράδειγμα: <placeholder-1/>Έτσι θα πρέπει ή να αποφύγετε αυτήν την κατάσταση ή να χρησιμοποιήσετε <ulink url="http://developer.gnome.org/glibmm/unstable/classGlib_1_1ustring.html"><function>Glib::ustring::compose()</function></ulink> που υποστηρίζει σύνταξη όπως: <placeholder-1/>Έτσι, για παράδειγμα, αν έχετε ένα γραφικό συστατικό <classname>Scale</classname> και θέλετε να αλλάξετε την περιστροφή μιας εικόνας όποτε η τιμή του αλλάζει, θα πρέπει να δημιουργήσετε έναν χειριστή σήματος, όπως αυτόν:Δότες (Sockets)Μερικά γραφικά συστατικά της <application>gtkmm</application> δεν έχουν συσχετισμένα παράθυρα Χ· σχεδιάζονται στα γονικά τους παράθυρα. Λόγω αυτού, δεν μπορούν να δεχτούν συμβάντα. Επίσης, αν είναι λαθεμένα σε μέγεθος, δεν περικόπτονται, έτσι μπορείτε να δεχτείτε μπερδεμένη αντικατάσταση κλπ. Για την λήψη συμβάντων σε ένα από αυτά τα γραφικά συστατικά, μπορείτε να το τοποθετήσετε μέσα σε ένα γραφικό συστατικό <classname>EventBox</classname> και έπειτα να καλέσετε <methodname>Gtk::Widget::set_events()</methodname> στο EventBox πριν το εμφανίσετε.Μερικές API που σχετίζονται με τη gtkmm χρησιμοποιούν ενδιάμεσους περιέκτες δεδομένων, όπως <classname>Glib::StringArrayHandle</classname>, αντί για ειδικό τυπικό περιέκτη C++ όπως <classname>std::vector</classname> ή <classname>std::list</classname>, αν και το ίδιο το <application>gtkmm</application> τώρα χρησιμοποιεί απλά <classname>std::vector</classname> από το <application>gtkmm</application> 3.0.Μερικά γραφικά συστατικά δεν έχουν συνδεμένο ένα X-Window, έτσι δεν δέχονται συνεπώς συμβάντα Χ. Αυτό σημαίνει ότι τα σήματα που περιγράφηκαν στην ενότητα <link linkend="sec-xeventsignals">σήματα συμβάντων Χ</link> δεν θα εκπεμφθούν. Αν θέλετε να συλλάβετε συμβάντα για αυτά τα γραφικά συστατικά, μπορείτε να χρησιμοποιήσετε έναν ειδικό περιέκτη που λέγεται <classname>Gtk::EventBox</classname> και περιγράφεται στην ενότητα <link linkend="sec-eventbox">Πλαίσια συμβάντων</link>.Κάποιες πρόσθετες μακροεντολές το κάνουν ευκολότερο και ομοιόμορφο. Ψάξτε στα αρχεία .m4 της gtkmm για παραδείγματα. Για παράδειγμα: <placeholder-1/>Κάποια αντικείμενα, όπως <classname>Gdk::Pixbuf</classname>s και <classname>Pango::Font</classname>s, παίρνονται από μια κοινόχρηστη μνήμη. Συνεπώς δεν μπορείτε να δημιουργήσετε τα δικά σας στιγμιότυπα. Αυτές οι κλάσεις τυπικά κληρονομούν από την <classname>Glib::Object</classname>. Αντί να σας ζητιέται να αναφέρετε και να αποαναφέρετε αυτά τα αντικείμενα, η <application>gtkmm</application> χρησιμοποιεί τον έξυπνο δείκτη <classname>Glib::RefPtr&lt;&gt;</classname>. Το Cairomm έχει τον δικό του έξυπνο δείκτη, <classname>Cairo::RefPtr&lt;&gt;</classname>.Μερικοί από τους βασικούς τύπους που χρησιμοποιούνται στα APIs της C έχουν καλύτερες εναλλακτικές στη C++. Για παράδειγμα, δεν υπάρχει ανάγκη για έναν τύπο <type>gboolean</type> αφού η C++ έχει <type>bool</type>. Ο παρακάτω κατάλογος δείχνει μερικούς κοινά χρησιμοποιούμενους τύπους στις APIs C και σε τι μπορείτε να τους μετατρέψετε σε μια βιβλιοθήκη συσκευαστή C++.Μερικοί κανόνες ασφάλειας νημάτων με τη χρήση της <classname>Glib::Dispatcher</classname> εφαρμόζονται ακόμα. Όπως αναφέρθηκε, ένα αντικείμενο <classname>Glib::Dispatcher</classname> πρέπει να δομηθεί στο νήμα δέκτη (το νήμα του οποίου ο κύριος βρόχος θα εκτελέσει τις συνδεμένες υποδοχές του). Από προεπιλογή, αυτό είναι το κύριο νήμα του προγράμματος, αν και υπάρχει ένας κατασκευαστής <classname>Glib::Dispatcher</classname> που μπορεί να πάρει το αντικείμενο <classname>Glib::MainContext</classname> οποιουδήποτε νήματος που έχει έναν κύριο βρόχο. Μόνο το νήμα του δέκτη πρέπει να καλέσει την <methodname>connect()</methodname> στο αντικείμενο <classname>Glib::Dispatcher</classname>, ή να χειριστεί οποιοδήποτε σχετικό αντικείμενο <classname>sigc::connection</classname>, εκτός και πρόσθετος συγχρονισμός χρησιμοποιείται. Όμως, οποιοδήποτε νήμα εργασίας μπορεί να εκπέμψει με ασφάλεια στο αντικείμενο <classname>Glib::Dispatcher</classname> χωρίς οποιοδήποτε κλείδωμα μόλις το νήμα του δέκτη έχει συνδέσει τις υποδοχές, με την προϋπόθεση ότι είναι δομημένο πριν το νήμα εργασίας να ξεκινήσει (αν είναι δομημένο μετά την έναρξη του νήματος, απαιτείται κανονικά πρόσθετος συγχρονισμός για να εξασφαλιστεί η ορατότητα).Μερικές φορές δύο αγγλικές συμβολοσειρές είναι ταυτόσημες, αλλά έχουν διαφορετικά νοήματα σε διαφορετικά περιεχόμενα, έτσι μπορεί προφανώς να μην είναι ταυτόσημα όταν μεταφράζονται. Αφού οι αγγλικές συμβολοσειρές χρησιμοποιούνται ως κλειδιά αναζήτησης, αυτό προκαλεί προβλήματα.ΤαξινόμησηΤαξινόμηση πατώντας στις στήλεςΠηγαίος κώδικαςΠηγές και προορισμοίΚαθορίζει τον κατάλογο προορισμού για τις δημιουργούμενες πηγές και το όνομα του κύριου αρχείου .defs που η <command>gmmproc</command> πρέπει να αναλύσει.Καθορίζει το όνομα της παραμέτρου υποδοχής της μεθόδου, αν έχει μία. Αυτό ενεργοποιεί την <command>gmmproc</command> για να δημιουργήσει κώδικα για αντιγραφή της υποδοχής και πέρασμα του αντιγράφου στη συνάρτηση C στην τελική της παράμετρο <literal>gpointer user_data</literal>. Η επιλογή <literal>slot_callback</literal> πρέπει επίσης να χρησιμοποιηθεί για τον ορισμό του ονόματος της συνάρτησης επανάκλησης επικόλλησης για να περάσει επίσης στη συνάρτηση C.Ορίζοντας τις λεπτομέρειες CellRendererΚουμπί αυξομείωσηςΞεκινήστε το πρόγραμμα <filename>plug</filename> και στείλτε το στο παρασκήνιο (ή απλά χρησιμοποιήστε ένα διαφορετικό τερματικό).Έτοιμα στοιχεία συνιστώνται για χρήση στα κουμπιά. Από την <application>gtkmm</application>-3.10 είναι ξεπερασμένα. Δεν πρέπει να χρησιμοποιηθούν σε νεογραμμένο κώδικα. Όμως, η τεκμηρίωση του <ulink url="http://developer.gnome.org/gtkmm/unstable/namespaceGtk_1_1Stock.html">namespace Gtk::Stock</ulink> εμφανίζει συνιστώμενες ετικέτες και επώνυμα εικονίδια να εμφανίζονται στα κουμπιά.Οι κυριολεκτικές συμβολοσειρές πρέπει να πληκτρολογηθούν στα αγγλικά, αλλά περιβαλόμενες από μια μακροεντολή. Το εργαλείο <application>gettext</application> (ή intltool) μπορεί τότε να εξάγει τις σημειωμένες συμβολοσειρές για μετάφραση και να αντικαταστήσει το μεταφρασμένο κείμενο στον χρόνο εκτέλεσης.Οι κυριολεκτικές συμβολοσειρές πρέπει να πληκτρολογηθούν στον πηγαίο κώδικα στα αγγλικά, αλλά θα πρέπει να περιβάλλονται από μια κλήση στη συνάρτηση <function>gettext()</function>. Αυτές οι συμβολοσειρές θα εξαχθούν για μετάφραση και οι μεταφράσεις μπορούν να χρησιμοποιηθούν στον χρόνο εκτέλεσης αντί για τις αρχικές αγγλικές συμβολοσειρές.Τα γραφικά συστατικά υποκλάσεων για καλύτερη οργάνωση του κώδικά σας. Θα πρέπει προφανώς να δημιουργήσετε υποκλάσεις στο κύριο <classname>Window</classname> σας τουλάχιστον. Έπειτα μπορείτε να κάνετε τα θυγατρικά γραφικά συστατικά σας και τα μέλη χειριστών σημάτων αυτής της κλάσης.Η δημιουργία υποκλάσεων δεν είναι πάντα ο καλύτερος τρόπος πραγματοποίησης. Είναι χρήσιμος μόνο όταν θέλετε το γραφικό συστατικό να χειρίζεται το δικό του σήμα από μόνο του. Αν θέλετε κάποια άλλη κλάση να χειρίζεται το σήμα, τότε θα χρειαστείτε να συνδέσετε έναν ξεχωριστό χειριστή. Αυτό είναι ακόμα περισσότερο αληθές, αν θέλετε αρκετά αντικείμενα να χειρίζονται το ίδιο σήμα, ή αν θέλετε ένας χειριστής σήματος να απαντά στο ίδιο σήμα από διαφορετικά αντικείμενα.ΠίνακαςTagTableΕτικέτεςΕτικέτες και μορφοποίησηΠροορισμοίΛέει στην <command>gmmproc</command> να μην περάσει ένα αντίγραφο της υποδοχής στη συνάρτηση C, αν η μέθοδος έχει ένα. Αντίθετα περνιέται η ίδια η υποδοχή. Το όνομα της παραμέτρου υποδοχής και η συνάρτηση επανάκλησης επικόλλησης πρέπει να έχουν οριστεί με τις επιλογές <literal>slot_name</literal> και <literal>slot_callbback</literal> αντίστοιχα.Λέει στην <command>gmmproc</command> για να προσθέσει κώδικα αρχικοποίησης για τη διεπαφή.Λέει στην <command>gmmproc</command> για να προσθέσει μερικούς τύπους ορισμού, κατασκευαστές και τυπικές μεθόδους σε αυτήν την κλάση ως κατάλληλους κατά την συσκευασία ενός γραφικού συστατικού.Λέει στην <command>gmmproc</command> να συμπεριλάβει μια κεφαλίδα στο δημιουργημένο αρχείο private/button_p.h.Δοκιμή και προσθήκη μεταφράσεωνΤο κείμενο σχεδιάζεται μέσα από διατάξεις Pango. Ο πιο εύκολος τρόπος για δημιουργία μιας <classname>Pango::Layout</classname> είναι η χρήση μιας <methodname>Gtk::Widget::create_pango_layout()</methodname>. Μόλις δημιουργηθεί, η διάταξη μπορεί να επεξεργαστεί με ποικίλους τρόπους, συμπεριλαμβάνοντας αλλαγή κειμένου, γραμματοσειράς, κλπ. Τελικά, η διάταξη μπορεί να απεικονιστεί χρησιμοποιώντας τη μέθοδο <methodname>Pango::Layout::show_in_cairo_context()</methodname>.Η απόδοση κειμένου γίνεται χρησιμοποιώντας Pango. Το αντικείμενο <classname>Pango::Layout</classname> για την εκτύπωση πρέπει να δημιουργηθεί καλώντας τη μέθοδο <methodname>PrintContext::create_pango_layout()</methodname>. Το αντικείμενο <classname>PrintContext</classname> παρέχει επίσης τα μετρικά της σελίδας, μέσα από την <methodname>get_width()</methodname> και <methodname>get_height()</methodname>. Ο αριθμός των σελίδων μπορεί να οριστεί με την <methodname>PrintOperation::set_n_pages()</methodname>. Για ενεργή απόδοση του κειμένου Pango στην <literal>on_draw_page</literal>, πάρτε μια <classname>Cairo::Context</classname> με <methodname>PrintContext::get_cairo_context()</methodname> και εμφανίστε τις <classname>Pango::LayoutLine</classname>s που εμφανίζονται μέσα στον ζητούμενο αριθμό σελίδας.TextViewΑυτό θα δημιουργήσει ένα αρχείο με όνομα <filename>programname.pot</filename>. Τώρα, αντιγράψτε αυτό το αρχείο στο <filename>languagecode.po</filename>, όπως <filename>de.po</filename> ή <filename>hu.po</filename>. Προσθέστε επίσης αυτόν τον κώδικα γλώσσας στο <literal>LINGUAS</literal>. Το αρχείο <filename>.po</filename> περιέχει μια κεφαλίδα και έναν κατάλογο αγγλικών συμβολοσειρών, με χώρο για τις μεταφρασμένες συμβολοσειρές που θα εισαχθούν. Βεβαιωθείτε ότι ορίσατε την κωδικοποίηση του αρχείου <filename>.po</filename> (καθορισμένη στην κεφαλίδα, αλλά επίσης ως περιεχόμενο) στο <literal>UTF-8</literal>.Το "αλλαγμένο" σήμαΗ επιλογή 'εκτύπωση σε αρχείο' είναι διαθέσιμη στον διάλογο εκτύπωσης, χωρίς την ανάγκη πρόσθετης υλοποίησης. Όμως, είναι χρήσιμο μερικές φορές να δημιουργήσετε ένα αρχείο pdf άμεσα από κώδικα. Για παράδειγμα, <placeholder-1/>Τα αρχεία .h και .cc θα δημιουργηθούν από τα αρχεία .hg και .ccg με επεξεργασία τους με την <command>gmmproc</command> έτσι, αν και αυτό συμβαίνει αυτόματα όταν χρησιμοποιείτε την παραπάνω δομή κατασκευής: <placeholder-1/>Τα αρχεία .hg και .ccgΤα πηγαία αρχεία .hg και .ccg είναι πολύ παρόμοια. με τα πηγαία αρχεία .h και .cc της C++, αλλά περιέχουν πρόσθετες μακροεντολές, όπως <function>_CLASS_GOBJECT()</function> και <function>_WRAP_METHOD()</function>, από τις οποίες η <command>gmmproc</command> δημιουργεί κατάλληλο πηγαίο κώδικα C++, συνήθως στην ίδια θέση στην κεφαλίδα. Οποιοσδήποτε πρόσθετος πηγαίος κώδικας C++ θα αντιγραφεί κατά λέξη στο αντίστοιχο αρχείο .h ή .cc.Το πακέτο <application>GNU gettext</application> επιτρέπει να σημειώσετε συμβολοσειρές στον πηγαίο κώδικα, να εξάγετε αυτές τις συμβολοσειρές για μετάφραση και να χρησιμοποιήσετε τις μεταφρασμένες συμβολοσειρές στην εφαρμογή σας.Η ενότητα <application>gtkmm</application> ορίζεται στην ομάδα ενότητας <filename>gnome-suites-core-deps-3.x.modules</filename>, έτσι επεξεργαστείτε το αρχείο σας <filename>.jhbuildrc</filename> και ορίστε τη ρύθμιση της ομάδας ενοτήτων σας στην τελευταία έκδοση π.χ. ως εξής: <placeholder-1/>Η <classname>AboutDialog</classname> προσφέρει έναν απλό τρόπο εμφάνισης πληροφοριών για ένα πρόγραμμα, όπως τον λογότυπο του,όνομα, πνευματικά δικαιώματα, ιστότοπο και άδεια.Το γραφικό συστατικό <classname>Alignment</classname> επιτρέπει την τοποθέτηση ενός γραφικού συστατικού σε μια θέση και μέγεθος σχετικά με το μέγεθος του ίδιου του γραφικού συστατικού <classname>Alignment</classname>. Για παράδειγμα, μπορεί να χρησιμοποιηθεί για κεντράρισμα ενός γραφικού συστατικού.Το γραφικό συστατικό <classname>AspectFrame</classname> φαίνεται σαν ένα γραφικό συστατικό <classname>Frame</classname>, αλλά εξαναγκάζει επίσης την <emphasis>αναλογία διαστάσεων</emphasis> (ο λόγος του πλάτους προς το ύψος) του θυγατρικού γραφικού συστατικού, προσθέτοντας πρόσθετο χώρο, αν είναι απαραίτητο. Για παράδειγμα, αυτό μπορεί να επιτρέψει την εμφάνιση μιας φωτογραφίας χωρίς να επιτρέπει στον χρήστη να την παραμόρφωση οριζόντια ή κάθετα κατά την αυξομείωση.Η <classname>ColorChooserDialog</classname> επιτρέπει στον χρήστη να διαλέξει ένα χρώμα. Η <classname>ColorButton</classname> ανοίγει έναν διάλογο επιλογής χρώματος όταν πατιέται.Το γραφικό συστατικό <classname>ComboBox</classname> προσφέρει μια λίστα (ή δένδρο) των επιλογών σε ένα πτυσσόμενο μενού. Αν είναι κατάλληλο, μπορεί να εμφανίσει πρόσθετες πληροφορίες για κάθε στοιχείο, όπως κείμενο, εικόνα, πλαίσιο ελέγχου, ή μια γραμμή προόδου. Το γραφικό συστατικό <classname>ComboBox</classname> συνήθως περιορίζει τον χρήστη στις διαθέσιμες επιλογές, αλλά μπορεί προαιρετικά να έχει μια <classname>Entry</classname>, που επιτρέπει στον χρήστη να εισάγει ελεύθερο κείμενο αν καμιά από τις διαθέσιμες επιλογές δεν είναι κατάλληλη.Το γραφικό συστατικό <classname>DrawingArea</classname> είναι ένα κενό παράθυρο που σας δίνει την ελευθερία της δημιουργίας οποιουδήποτε γραφικού επιθυμείτε. Μαζί με την ελευθερία έρχεται η ευθύνη χειρισμού σημάτων σχεδίασης στο γραφικό συστατικό. Όταν ένα γραφικό συστατικό πρωτοεμφανίζεται, ή όταν καλύπτεται και έπειτα αποκαλύπτεται ξανά, χρειάζεται να ανασχεδιαστεί. Τα περισσότερα γραφικά συστατικά έχουν κώδικα για να το κάνουν αυτό, αλλά το DrawingArea δεν έχει, επιτρέποντας σας να γράψετε τον δικό σας χειριστή σήματος για να προσδιορίσετε πώς τα περιεχόμενα του γραφικού συστατικού θα σχεδιαστούν. Αυτό γίνεται συχνά με αντικατάσταση της εικονικής συνάρτησης μέλους <methodname>on_draw()</methodname>.Η <classname>EntryCompletion</classname> μπορεί να χρησιμοποιήσει ένα <classname>TreeModel</classname> που περιέχει πιθανές καταχωρίσεις, που ορίστηκαν με <methodname>set_model()</methodname>. Τότε θα πρέπει να καλέσετε την <methodname>set_text_column()</methodname> για να ορίσετε ποιες στήλες του προτύπου σας πρέπει να χρησιμοποιηθούν για να ταιριάζουν με πιθανές καταχωρίσεις κειμένου.Η <classname>FileChooserDialog</classname> είναι κατάλληλη για χρήση με στοιχεία μενού "Άνοιγμα" ή "Αποθήκευση".Η <classname>FontChooserDialog</classname> επιτρέπει στον χρήστη να διαλέξει μία γραμματοσειρά. Η <classname>FontButton</classname> ανοίγει έναν διάλογο επιλογής γραμματοσειράς όταν πατιέται.Η <classname>Gdk::Pixbuf</classname> μπορεί να απεικονιστεί ορίζοντας την ως το πηγαίο υπόδειγμα του περιεχομένου Cairo με την <methodname>Gdk::Cairo::set_source_pixbuf()</methodname>. Έπειτα, σχεδιάστε την εικόνα με είτε <methodname>Cairo::Context::paint()</methodname> (για σχεδίαση ολόκληρης της εικόνας), ή <methodname>Cairo::Context::rectangle()</methodname> και <methodname>Cairo::Context::fill()</methodname> (για γέμισμα του συγκεκριμένου ορθογωνίου). Η <methodname>set_source_pixbuf()</methodname> δεν είναι μέλος της <classname>Cairo::Context</classname>. Παίρνει μια <classname>Cairo::Context</classname> ως την πρώτη της παράμετρο.Το <classname>Gtk::Adjustment</classname> δημιουργείται από την μέθοδο του <methodname>create()</methodname> που έχει ως εξής:Το γραφικό συστατικό <classname>Gtk::Button</classname> έχει τα παρακάτω σήματα, αλλά τον περισσότερο χρόνο θα χειρίζεστε μόνο το <literal>clicked</literal> (πατημένο) σήμα:Το γραφικό συστατικό <classname>Gtk::TreeView</classname> μπορεί να περιέχει λίστες ή δένδρα δεδομένων, σε στήλες.Η <classname>ListStore</classname> περιέχει απλές γραμμές δεδομένων και κάθε γραμμή δεν έχει θυγατρικά.Η κλάση <classname>PrintOperation</classname> έχει μια μέθοδο που λέγεται <methodname>set_default_page_setup()</methodname> που επιλέγει το προεπιλεγμένο μέγεθος χαρτιού, προσανατολισμό και περιθώρια. Για την εμφάνιση διαλόγου ρύθμισης της σελίδας από την εφαρμογή σας, χρησιμοποιήστε τη μέθοδο <methodname>Gtk::run_page_setup_dialog()</methodname>, που επιστρέφει ένα αντικείμενο <classname>Gtk::PageSetup</classname> με τις επιλεγμένες ρυθμίσεις. Χρησιμοποιήστε αυτό το αντικείμενο για ενημέρωση μιας <classname>PrintOperation</classname> και πρόσβαση των επιλεγμένων <classname>Gtk::PaperSize</classname>, <literal>Gtk::PageOrientation</literal> και των ειδικών περιθωρίων του εκτυπωτή.Η <classname>SpinButton</classname> μπορεί να δημιουργήσει μια προεπιλεγμένη <classname>Adjustment</classname>, που μπορείτε να προσπελάσετε μέσα από τη μέθοδο <methodname>get_adjustment()</methodname>, ή μπορείτε να ορίσετε μια υπάρχουσα <classname>Adjustment</classname> στον κατασκευαστή.Η κλάση <classname>Tag</classname> έχει πολλές άλλες ιδιότητες.Η <classname>TextView</classname> δημιουργεί τη δική της προεπιλογή <classname>TextBuffer</classname>, που μπορείτε να προσπελάσετε μέσα από τη μέθοδο <methodname>get_buffer()</methodname>.Το γραφικό συστατικό <classname>TextView</classname> μπορεί να χρησιμοποιηθεί για την εμφάνιση και επεξεργασία μεγάλων ποσοτήτων μορφοποιημένου κειμένου. Όπως η <classname>TreeView</classname>, έχει μια σχεδίαση προτύπου/προβολής. Σε αυτήν την περίπτωση η <classname>TextBuffer</classname> είναι το πρότυπο.Τα στοιχεία της <classname>ToolPalette</classname> μπορεί να μετακινηθούν ή απλά να ενεργοποιηθούν. Για παράδειγμα, ο χρήστης μπορεί να μετακινήσει αντικείμενα σε ένα καμβά για να δημιουργήσει νέα στοιχεία εκεί. Ή ο χρήστης μπορεί να πατήσει ένα στοιχείο για να ενεργοποιήσει ένα συγκεκριμένο μέγεθος πινέλου σε μια εφαρμογή σχεδίασης.Η κλάση <classname>TreeModelColumnRecord</classname> χρησιμοποιείται για διατήρηση ανίχνευσης των στηλών και των τύπων δεδομένων τους. Προσθέτετε στιγμιότυπα <classname>TreeModelColumn</classname> στη <classname>ColumnRecord</classname> και έπειτα τα χρησιμοποιείτε στη <classname>TreeModelColumns</classname>, όταν παίρνετε και ορίζετε τα δεδομένα στις γραμμές του προτύπου. Θα το βρείτε προφανώς βολικό να παράξετε μια νέα <classname>TreeModelColumnRecord</classname> που έχει τα στιγμιότυπά σας στη <classname>TreeModelColumn</classname> ως δεδομένα μέλους.Η <classname>TreeStore</classname> περιέχει γραμμές δεδομένων και κάθε γραμμή μπορεί να έχει θυγατρικές γραμμές.Η <classname>TreeView</classname> επιτρέπει ήδη να εμφανίσετε την ίδια <classname>TreeModel</classname> σε δύο γραφικά συστατικά <classname>TreeView</classname>. Αν χρειάζεστε μια από αυτές τις TreeViews για να ταξινομήσετε το πρότυπο διαφορετικά από την άλλη, τότε θα πρέπει να χρησιμοποιήσετε μια <classname>TreeModelSort</classname> αντί για απλώς, για παράδειγμα, <methodname>Gtk::TreeViewModel::set_sort_column()</methodname>. Η <classname>TreeModelSort</classname> είναι ένα πρότυπο που περιέχει ένα άλλο πρότυπο, που παρουσιάζει μια ταξινομημένη έκδοση αυτού του προτύπου. Για παράδειγμα, μπορεί να προσθέσετε μια ταξινομημένη έκδοση ενός προτύπου σε μια <classname>TreeView</classname> ως εξής:Η κλάση <classname>Widget</classname> έχει μερικά ειδικά σήματα που αντιστοιχούν με τα υποκείμενα συμβάντα X-Windows. Αυτά έχουν ως επίθημα από την <literal>_event</literal>· για παράδειγμα, η <methodname>Widget::signal_button_press_event()</methodname>.Η <emphasis>πολιτική ενημέρωσης</emphasis> του γραφικού συστατικού <classname>Range</classname> ορίζει σε ποια σημεία κατά τη διάρκεια αλληλεπίδρασης τους χρήστη, θα αλλάξει το πεδίο <literal>value</literal> της <classname>Gtk::Adjustment</classname> και θα εκπέμψει το σήμα <literal>value_changed</literal>. Οι πολιτικές ενημέρωσης, που ορίστηκαν με τη μέθοδο <methodname>set_update_policy()</methodname>, είναι: <placeholder-1/>Τα αρχεία <filename>.defs</filename> είναι αρχεία κειμένου, σε μια μορφή lisp, που περιγράφει την API μιας βιβλιοθήκης C, συμπεριλαμβανόμενου του <placeholder-1/>Το σενάριο <filename>configure</filename> (διαμόρφωση) θα ελέγξει για να διασφαλίσει ότι όλες οι απαιτούμενες εξαρτήσεις έχουν ήδη εγκατασταθεί. Αν σας λείπει κάποια εξάρτηση, θα εξέλθει και θα εμφανίσει ένα σφάλμα.Το σενάριο <filename>skeletonmm/codegen/generate_defs_and_docs.sh</filename> δημιουργεί όλα τα αρχεία <filename>.defs</filename> και το αρχείο <filename>*_docs.xml</filename>, που περιγράφηκε στην ενότητα <link linkend="sec-wrapping-documentation">τεκμηρίωση</link>.Η ομάδα <function>AC_CONFIG_FILES()</function> πρέπει να αναφέρει τα σωστά ονόματα καταλόγου, όπως περιγράφηκαν παραπάνω.Η γραμμή <function>AC_CONFIG_HEADERS()</function> χρησιμοποιείται για τη δημιουργία δύο ή περισσότερων αρχείων κεφαλίδας ρυθμίσεων.Το πρώτο αρχείο κεφαλίδας στη κατάλογο περιέχει όλες τις μακροεντολές ρύθμισης, που ορίζονται κατά τη διάρκεια της εκτέλεσης ρύθμισης. Οι υπολειπόμενες κεφαλίδες στον κατάλογο περιέχουν μόνο ένα υποσύνολο των μακροεντολών ρυθμίσεων και του αντίστοιχου τους αρχείου <filename>configh.h.in</filename> που δεν θα αυτοδημιουργηθούν. Η αιτία για αυτόν τον διαχωρισμό είναι ότι οι κεφαλίδες ρυθμίσεων χώρου ονόματος είναι εγκατεστημένες με τη βιβλιοθήκη σας και ορίζουν δημόσια ορατές μακροεντολές.Η γραμμή <function>AC_CONFIG_SRCDIR()</function> πρέπει να αναφέρει ένα αρχείο στο πηγαίο σας δένδρο. Μπορούμε να το επεξεργαστούμε αργότερα, αν δεν ξέρουμε ακόμα τα ονόματα οποιουδήποτε από τα αρχεία που θα δημιουργήσουμε.Η γραμμή <function>AC_SUBST([SOMETHINGMM_MODULES], ['...'])</function> μπορεί να χρειαστεί να τροποποιηθεί για να ελέγξει τις σωστές εξαρτήσεις.Οι μακροεντολές <function>_CTOR_DEFAULT()</function> και <function>_WRAP_CTOR()</function> προσθέτουν κατασκευαστές συσκευάζοντας τις συγκεκριμένες συναρτήσεις C <function>*_new()</function>. Αυτές οι μακροεντολές θεωρούν ότι το αντικείμενο C έχει ιδιότητες με τα ίδια ονόματα όπως οι παράμετροι συνάρτησης, όπως συνήθως συμβαίνει, έτσι ώστε να μπορεί να παράσχει τις παραμέτρους άμεσα σε μια κλήση <function>g_object_new()</function>. Αυτοί οι κατασκευαστές στην πραγματικότητα δεν καλούν ποτέ τις συναρτήσεις C <function>*_new()</function>, επειδή η gtkmm πρέπει στην πραγματικότητα να αρχικοποιήσει παράγωγους GTypes και οι συναρτήσεις C <function>*_new()</function> νοούνται μόνο ως συναρτήσεις διευκόλυνσης για προγραμματιστές C.Η API της <link linkend="chapter-draganddrop">Μεταφοράς και απόθεσης</link> χρησιμοποιεί τον ίδιο μηχανισμό. Θα πρέπει προφανώς να χρησιμοποιήσετε τα ίδια δεδομένα προορισμών και μορφών και για το πρόχειρο και για τη μεταφορά και απόθεση.Η <literal>const ... &amp;</literal> γύρω και από τις δύο είναι απλά για αποτελεσματικότητα, όπως η χρήση της <classname>const std::string&amp;</classname> αντί για την <classname>std::string</classname> για μια παράμετρο μεθόδου για αποφυγή περιττών αντιγραφών.Το <literal>ideal</literal> παράδειγμα παρακάτω μπορεί να δώσει περισσότερους από έναν προορισμούς προχείρου.Η μέθοδος <methodname>PrintOperation::run()</methodname> ξεκινά τον βρόχο εκτύπωσης, κατά τη διάρκεια του οποίου ποικίλα σήματα εκπέμπονται: <placeholder-1/>Οι εικονικές μέθοδοι <methodname>get_request_mode_vfunc()</methodname>, <methodname>get_preferred_width_vfunc()</methodname>, <methodname>get_preferred_height_vfunc()</methodname>, <methodname>get_preferred_width_for_height_vfunc()</methodname>, <methodname>get_preferred_height_for_width_vfunc()</methodname> και <methodname>on_size_allocate()</methodname> ελέγχουν τη διάταξη των θυγατρικών γραφικών συστατικών. Για παράδειγμα, αν ο περιέκτης σας έχει 2 θυγατρικά γραφικά συστατικά, με το ένα κάτω από το άλλο, η <methodname>get_request_mode_vfunc()</methodname> μπορεί να ζητήσει διάταξη ύψους προς πλάτος. Έπειτα η <methodname>get_preferred_width_vfunc()</methodname> σας μπορεί να αναφέρει το μέγιστο των πλατών των θυγατρικών γραφικών συστατικών και η <methodname>get_preferred_height_for_width_vfunc()</methodname> μπορεί να αναφέρει το άθροισμα των υψών τους. Αν θέλετε συμπλήρωση μεταξύ των θυγατρικών γραφικών συστατικών, τότε θα πρέπει να το προσθέσετε στο πλάτος και στο ύψος επίσης. Ο περιέκτης του γραφικού συστατικού θα χρησιμοποιήσει αυτό το αποτέλεσμα για να εξασφαλίσει ότι το γραφικό συστατικό σας έχει αρκετό χώρο και όχι μικρότερο. Εξετάζοντας κάθε γονικό του θυγατρικού συστατικού και το γονικό του, θα αποφασίσει τελικά η λογική για το μέγεθος του παραθύρου ανωτάτου επιπέδου.Οι μέθοδοι <methodname>pack_start()</methodname> και <methodname>pack_end()</methodname> τοποθέτησης γραφικών συστατικών μέσα σε αυτούς τους περιέκτες. Η μέθοδος <methodname>pack_start()</methodname> θα ξεκινήσει στην κορυφή και θα δουλέψει τον τρόπο της κάτω σε ένα <classname>Box</classname> με κάθετο προσανατολισμό, ή θα συσκευάσει από αριστερά προς τα δεξιά σε ένα <classname>Box</classname> με οριζόντιο προσανατολισμό. Η <methodname>pack_end()</methodname> θα κάνει το αντίθετο, συσκευάζοντας από κάτω προς τα πάνω ή από δεξιά προς τα αριστερά. Η χρήση αυτών των μεθόδων επιτρέπει τη δεξιά ή αριστερή στοίχιση των γραφικών συστατικών μας. Θα χρησιμοποιήσουμε τη <methodname>pack_start()</methodname> στα περισσότερα παραδείγματά μας.Η μέθοδος <methodname>run()</methodname> επιστρέφει έναν <literal>int</literal>. Αυτός μπορεί να είναι μια τιμή από την <literal>Gtk::ResponseType</literal> αν ο χρήστης έκλεισε τον διάλογο πατώντας ένα τυπικό κουμπί, ή μπορεί να είναι η προσαρμοσμένη τιμή απάντησης που ορίσατε, όταν χρησιμοποιήσατε <methodname>add_button()</methodname>.Η μέθοδος <methodname>spin()</methodname> 'αυξομειώνει' την <classname>SpinButton</classname>, ως εάν τα κουμπιά της αύξησης ή μείωσης να είχαν πατηθεί. Χρειάζεται να ορίσετε μια <classname>Gtk::SpinType</classname> για να ορίσετε την κατεύθυνση ή τη νέα θέση.Το όρισμα <parameter>options</parameter> μπορεί να πάρει μία από αυτές τις τρεις επιλογές: <placeholder-1/>Το όρισμα <parameter>padding</parameter> καθορίζει το πλάτος μιας πρόσθετης περιοχής περιγράμματος για να αφήσει ολόγυρα το συσκευασμένο γραφικό συστατικό.Το όρισμα <parameter>value</parameter> είναι η αρχική τιμή της προσαρμογής, που αντιστοιχεί συνήθως στην ανώτατη ή αριστερότερη θέση ενός προσαρμόσιμου γραφικού συστατικού. Τα ορίσματα <parameter>lower</parameter> και <parameter>upper</parameter> καθορίζουν τη δυνατή περιοχή τιμών που η προσαρμογή μπορεί να κρατήσει. Το όρισμα <parameter>step_increment</parameter> καθορίζει την μικρότερη από τις δύο αυξήσεις με τις οποίες ο χρήστης μπορεί να αλλάξει την τιμή, ενώ η <parameter>page_increment</parameter> είναι η μεγαλύτερη. Το όρισμα <parameter>page_size</parameter> συνήθως αντιστοιχεί κάπως στην ορατή περιοχή ενός μετακινούμενου γραφικού συστατικού. Το όρισμα <parameter>upper</parameter> χρησιμοποιείται για την αναπαράσταση της πιο μικρής ή πιο δεξιάς συντεταγμένης σε ένα θυγατρικό μετακινούμενο γραφικό συστατικό.Η ενδιάμεση μνήμηΗ συνάρτηση C (π.χ. <function>get_request_mode</function>) περιγράφεται πληρέστερα στο αρχείο <filename>*_vfuncs.defs</filename> και τα αρχεία <filename>convert*.m4</filename> περιέχουν την απαραίτητη μετατροπή από τον τύπο παραμέτρου C++ στον τύπο παραμέτρου C.Η συνάρτηση C (π.χ. <function>gtk_entry_set_text</function>) περιγράφεται πληρέστερα στο αρχείο .defs και τα αρχεία <filename>convert*.m4</filename> περιέχουν την απαραίτητη μετατροπή από τον τύπο παραμέτρου C++ στον τύπο παραμέτρου C. Αυτή η μακροεντολή επίσης παράγει σχόλια τεκμηρίωσης doxygen με βάση τα αρχεία <filename>*_docs.xml</filename> και <filename>*_docs_override.xml</filename>.Το πρότυπο σχεδίασης CairoΤο σύστημα συντεταγμένων Cairo, στον χειριστή <literal>draw_page</literal>, περιστρέφεται αυτόματα στον τρέχοντα προσανατολισμό της σελίδας. Είναι κανονικά μέσα στα περιθώρια του εκτυπωτή, αλλά μπορείτε να το αλλάξετε μέσα από τη μέθοδο <methodname>PrintOperation::set_use_full_page()</methodname>. Η προεπιλεγμένη μονάδα μέτρησης είναι εικονοστοιχεία συσκευής. Για επιλογή άλλων μονάδων, χρησιμοποιήστε τη μέθοδο <methodname>PrintOperation::set_unit()</methodname>.Το πρόχειροΤο γραφικό συστατικό περιοχής σχεδίασηςΤο πρότυποΟ έξυπνος δείκτης RefPtrΗ επιλογήΤο γραφικό συστατικό προβολή δένδρου (TreeView)Η διάταξη γραφικής διεπαφής για ένα αναδυόμενο μενού πρέπει να χρησιμοποιήσει τον κόμβο <literal>popup</literal>. Για παράδειγμα:Η προβολήΗ προβολή είναι το ενεργό γραφικό συστατικό (<classname>Gtk::TreeView</classname>) που εμφανίζει τα δεδομένα του προτύπου (<classname>Gtk::TreeModel</classname>) και επιτρέπει στον χρήστη να αλληλεπιδράσει με αυτά. Η προβολή μπορεί να εμφανίσει όλες τις στήλες του προτύπου, ή απλά μερικές και μπορεί να τις εμφανίσει με ποικίλους τρόπους.Τα προσαρμόσιμα γραφικά συστατικά μπορούν να διαιρεθούν χοντρικά σε αυτά τα οποία χρησιμοποιούν και απαιτούν ειδικές μονάδες για αυτές τις τιμές και σε αυτά που τα θεωρούν ως ελεύθερους αριθμούς.Τα ορίσματα στην <methodname>Action::create()</methodname> ορίζουν το όνομα της ενέργειας και πώς θα εμφανιστεί στα μενού και τις εργαλειοθήκες.Η βασική ιδέα σχεδίασης στο Cairo εμπεριέχει τον ορισμό 'αόρατων' μονοπατιών και έπειτα βάψιμο ή γέμισμά τους για να γίνουν ορατά.Η δομή δημιουργίαςΗ κλήση στη <methodname>Cairo::Context::curve_to()</methodname> πρέπει να είναι επαρκώς αυτονόητη. Το πρώτο ζεύγος συντεταγμένων ορίζει το σημείο ελέγχου για την αρχή της καμπύλης. Το δεύτερο σύνολο των συντεταγμένων ορίζει το σημείο ελέγχου για το τέλος της καμπύλης και το τελευταίο σύνολο συντεταγμένων ορίζει το σημείο προορισμού. Για τη διευκόλυνση της έννοιας των σημείων ελέγχου στην οπτικοποίηση, μια γραμμή έχει σχεδιαστεί από κάθε σημείο ελέγχου στο τελικό σημείο της καμπύλης με το οποίο σχετίζεται. Σημειώστε ότι αυτές οι γραμμές σημείων ελέγχου είναι και οι δυο ημιδιαφανείς. Αυτό πετυχαίνεται με μια παραλλαγή της <methodname>set_source_rgb()</methodname> που λέγεται <methodname>set_source_rgba()</methodname>. Αυτή η συνάρτηση παίρνει ένα τέταρτο όρισμα που ορίζει την τιμή άλφα του χρώματος (έγκυρες τιμές είναι μεταξύ 0 και 1).Το επιλεγμένο στοιχείοΗ μακροεντολή κλάσης δηλώνει την ίδια την κλάση και τη σχέση της με τον υποκείμενο τύπο C. Δημιουργεί κάποιους εσωτερικούς κατασκευαστές, το μέλος <varname>gobject_</varname>, ορισμούς τύπους, τα στοιχεία πρόσβασης <function>gobj()</function>, καταχώριση τύπου και τη μέθοδο <function>Glib::wrap()</function> μεταξύ άλλων.Η επανάκληση καθαρισμού επιτρέπει την απελευθέρωση χρησιμοποιούμενης μνήμης από τα αποθηκευμένα δεδομένα όταν το πρόχειρο αντικαθιστά τα δεδομένα του με κάτι άλλο.Οι επιλογές της γραμμής εντολών που πέρασαν στον προεπεξεργαστή C.Οι επιλογές της γραμμής εντολών που πέρασαν στον μεταγλωττιστή C++.Η επικοινωνία μεταξύ μιας <classname>Socket</classname> και μιας <classname>Plug</classname> ακολουθεί το πρωτόκολλο XEmbed. Αυτό το πρωτόκολλο έχει επίσης υλοποιηθεί σε άλλα πακέτα εργαλείων (π.χ. Qt), που επιτρέπουν το ίδιο επίπεδο ενσωμάτωσης όταν ενσωματώνεται ένα γραφικό συστατικό Qt σε GTK+ ή αντίστροφα.Ο μεταγλωττιστής θα παραπονεθεί αν χρησιμοποιήσετε έναν ακατάλληλο τύπο. Για παράδειγμα, αυτό θα μπορούσε να δημιουργήσει ένα σφάλμα μεταγλωττιστή:Οι παραλλαγές connect*_once(), <methodname>Glib::SignalIdle::connect_once()</methodname>, <methodname>Glib::SignalTimeout::connect_once()</methodname>, <methodname>Glib::SignalTimeout::connect_seconds_once()</methodname>, είναι με ασφάλεια νήματος για κάθε περίπτωση όπου η υποδοχή δεν δημιουργείται από μια κλήση στην <function>sigc::mem_fun()</function> που αντιπροσωπεύει μια μέθοδο κλάσης που παράγεται από την <classname>sigc::trackable</classname>. Αυτή είναι παρόμοια με την <methodname>Glib::Threads::Thread::create()</methodname> όπως αναφέρθηκε στο σημείο 4.Οι περιορισμοίΟ κατασκευαστής για την <classname>ExampleWindow</classname> δημιουργεί το μενού χρησιμοποιώντας την <classname>UIManager</classname> (δείτε <xref linkend="chapter-menus-and-toolbars"/> για περισσότερες πληροφορίες). Έπειτα προσθέτει το μενού και την εργαλειοθήκη στο παράθυρο.Ο κατασκευαστής για <classname>Gtk::EventBox</classname> είναι:Η τρέχουσα κατάσταση μιας <classname>Cairo::Context</classname> μπορεί να αποθηκευτεί σε μια εσωτερική στοίβα των αποθηκευμένων καταστάσεων και αργότερα να ανακτηθεί στην κατάσταση που ήταν όταν την αποθηκεύσατε. Για να το κάνετε αυτό, χρησιμοποιήστε τη μέθοδο <methodname>save()</methodname> και την μέθοδο <methodname>restore()</methodname>. Αυτό μπορεί να είναι χρήσιμο αν χρειάζεστε να αλλάξετε προσωρινά το πλάτος και το χρώμα της γραμμής (ή οποιαδήποτε άλλη ρύθμιση γραφικών) για να σχεδιάσετε κάτι και να επιστρέψετε έπειτα στις προηγούμενες ρυθμίσεις. Σε αυτήν την κατάσταση, μπορείτε να καλέσετε <methodname>Cairo::Context::save()</methodname>, να αλλάξετε τις ρυθμίσεις γραφικών, να σχεδιάσετε τις γραμμές, και έπειτα να καλέσετε <methodname>Cairo::Context::restore()</methodname> για να επαναφέρετε την αρχική κατάσταση γραφικών. Πολλαπλές κλήσεις στις <methodname>save()</methodname> και <methodname>restore()</methodname> μπορούν να ενσωματωθούν· κάθε κλήση στο <methodname>restore()</methodname> επαναφέρει την κατάσταση από το αντίστοιχο ζευγάρι <methodname>save()</methodname>. <placeholder-1/>Η προεπιλεγμένη <classname>CellRenderers</classname> και η προεπιλεγμένη τους συμπεριφορά κανονικά αρκούν, αλλά μπορεί ενίοτε να χρειαστείτε πιο λεπτό έλεγχο. Για παράδειγμα, αυτός ο κώδικας παραδείγματος από το <filename>gtkmm/demos/gtk-demo/example_treeview_treestore.cc</filename>, προσαρτά ένα γραφικό συστατικό <classname>Gtk::CellRenderer</classname> και το πληροφορεί για να αποδώσει τα δεδομένα από ποικίλες στήλες προτύπου μέσα από ποικίλες πτυχές της εμφάνισης του.Το γραφικό συστατικό προορισμού θα εκπέμψει αυτά τα σήματα, με αυτήν τη σειρά: <placeholder-1/>Τα σήματα μεταφοράς και απόθεσης παρέχουν ένα DragContext, που περιέχει κάποια πληροφορία για τη λειτουργία μεταφοράς και απόθεσης και μπορεί να χρησιμοποιηθεί για να επηρεάσει τη διεργασία. Για παράδειγμα, μπορείτε να ανακαλύψετε το πηγαίο γραφικό συστατικό, ή να αλλάξετε το εικονίδιο της μεταφοράς και απόθεσης, χρησιμοποιώντας τις μεθόδους <methodname>set_icon()</methodname>. Πιο σημαντικό, θα πρέπει να καλέσετε τη μέθοδο <methodname>drag_finish()</methodname> από τον χειριστή σήματός σας <literal>drag_data_received</literal> για να δείξετε αν η απόθεση ήταν πετυχημένη.Ο πιο εύκολος τρόπος για να το κάνετε αυτό είναι η χρήση της <ulink url="https://wiki.gnome.org/Jhbuild">jhbuild</ulink>. Η <application>jhbuild</application> είναι ένα πρόγραμμα που διευκολύνει τη δόμηση λογισμικού GNOME υπολογίζοντας τις εξαρτήσεις και δομώντας τα πράγματα με τη σωστή σειρά. Αυτή η ενότητα θα σας δώσει μια σύντομη εξήγηση πώς να εγκαταστήσετε την <application>jhbuild</application> για να δομήσετε και να εγκαταστήσετε την <application>gtkmm</application> από το πηγαίο αποθετήριο (git). Για τις ενημερωμένες πληροφορίες για την <application>jhbuild</application>, δείτε το <ulink url="http://developer.gnome.org/jhbuild/unstable/">εγχειρίδιο jhbuild</ulink>. Αν χρειάζεστε βοήθεια χρησιμοποιώντας την <application>jhbuild</application>, θα πρέπει να ζητήσετε για βοήθεια στην <ulink url="http://mail.gnome.org/mailman/listinfo/gnome-love">ταχυδρομική λίστα gnome-love</ulink>.Η καταχώρισηΤο συμβάν δίνεται πρώτα στο γραφικό συστατικό που συμβαίνει το συμβάν. Αν όλοι οι χειριστές σήματος σε αυτό το γραφικό συστατικό επιστρέψουν <literal>false</literal> (που δείχνει ότι το συμβάν δεν επεξεργάστηκε), τότε το σήμα θα διαδοθεί στο γονικό γραφικό συστατικό και θα εκπεμφθεί εκεί. Αυτό συνεχίζεται όλο τον δρόμο μέχρι το γραφικό συστατικό ανωτάτου επιπέδου, αν κανένας δεν χειριστεί το συμβάν.Το συμβάν θα διαδοθεί μέχρι να φτάσει στο γραφικό συστατικό ανωτάτου επιπέδου, ή μέχρι να σταματήστε τη διάδοση επιστρέφοντας <literal>true</literal> από έναν χειριστή συμβάντος.Το παράδειγμα στο examples/book/printing/advanced δείχνει αυτό.Ο πρόσθετος ορισμός τύπου επιτρέπει να χρησιμοποιηθεί η δομή σε μια κεφαλίδα χωρίς συμπερίληψη του πλήρους ορισμού της, απλά προδηλώνοντάς την, επαναλαμβάνοντας αυτόν τον τύπο ορισμού. Αυτό σημαίνει ότι δεν πρέπει να συμπεριλάβετε την κεφαλίδα της βιβλιοθήκης C στην κεφαλίδα της C++, κρατώντας την έξω από τη δημόσια API. Η <command>gmmproc</command> υποθέτει ότι αυτή η τεχνική χρησιμοποιήθηκε, έτσι θα δείτε σφάλματα μεταγλωττιστή αν αυτό δεν συμβαίνει.Οι πρώτες 6 μέθοδοι στον προηγούμενο πίνακα αντικαταστάθηκαν επίσης στους προσαρμοσμένους περιέκτες. Περιγράφονται συνοπτικά στην ενότητα <link linkend="sec-custom-containers">Προσαρμοσμένοι περιέκτες</link>.Το πρώτο όρισμα είναι μια <classname>slot</classname> που θέλετε να κληθεί όταν συμβαίνει λήξη χρόνου. Το δεύτερο όρισμα είναι ένας αριθμός χιλιοστών του δευτερολέπτου μεταξύ κλήσεων σε αυτήν τη μέθοδο. Δέχεστε ένα αντικείμενο <classname>sigc::connection</classname> που μπορεί να χρησιμοποιηθεί για απενεργοποίηση της σύνδεσης χρησιμοποιώντας τη μέθοδό του <methodname>disconnect()</methodname>:Το πρώτο όρισμα είναι μια σχισμή που θέλετε να κληθεί όταν το συγκεκριμένο συμβάν (δείτε όρισμα 3) συμβαίνει στον περιγραφέα του αρχείου που ορίσατε χρησιμοποιώντας το όρισμα δύο. Το όρισμα τρία μπορεί να είναι ένα ή περισσότερα (χρησιμοποιώντας <literal>|</literal>) των:Το πρώτο όρισμα είναι το γραφικό συστατικό που συσκευάζετε. Στο παράδειγμά μας όλα αυτά είναι <classname>Button</classname>s.Η πρώτη κλήση στην <methodname>connect()</methodname> είναι ακριβώς όπως αυτή που είδαμε την τελευταία φορά· τίποτα νέο εδώ.Η πρώτη γραμμή της εξόδου είναι από το <filename>plug</filename>, αφού έχει ειδοποιηθεί ότι έχει ενσωματωθεί μέσα σε μια <classname>Socket</classname>. Η δεύτερη γραμμή εκπέμφθηκε από το <filename>socket</filename> σε απάντηση του σήματός του <methodname>plug_added</methodname>. Αν όλα έγιναν όπως περιγράφτηκε παραπάνω, το παράθυρο <filename>socket</filename> πρέπει να φαίνεται χοντρικά όπως το παρακάτω:Το παρακάτω παράδειγμα δείχνει και τις δύο χρήσεις ενός <classname>EventBox</classname> - μια ετικέτα δημιουργείται που περικόπτεται σε ένα μικρό πλαίσιο και ρυθμίζεται έτσι ώστε με πάτημα του ποντικιού στην ετικέτα να προκαλεί έξοδο από το πρόγραμμα. Αυξομείωση του παραθύρου αποκαλύπτει ποικίλα ποσά της ετικέτας.Το παρακάτω παράδειγμα δείχνει πώς να εκτυπώσετε κάποια είσοδο από μια διεπαφή χρήστη. Εμφανίζει πώς να υλοποιήσετε τις <literal>on_begin_print</literal> και <literal>on_draw_page</literal>, καθώς και πώς να αναγνωρίστε την κατάσταση εκτύπωσης και πώς να ενημερώσετε τις ρυθμίσεις εκτύπωσης.Το παρακάτω παράδειγμα δείχνει τη χρήση των <classname>RadioButton</classname>:Το παρακάτω παράδειγμα προγράμματος απαιτεί μια επιλογή γραμμής εντολών. Ο πηγαίος κώδικας εμφανίζει δύο τρόπους χειρισμού των επιλογών της γραμμής εντολών σε συνδυασμό με την <classname>Gtk::Application</classname>.Το παρακάτω παράδειγμα εμφανίζει πώς να ρυθμιστεί ένα περιεχόμενο Cairo με ένα χρώμα προσκηνίου κόκκινου και ένα πλάτος 2. Οποιεσδήποτε λειτουργίες σχεδίασης που χρησιμοποιούν αυτό το περιεχόμενο θα χρησιμοποιήσουν αυτές τις ρυθμίσεις.Το παρακάτω είναι ένα απλό παράδειγμα χρήσης δεκτών και δοτών. Η μέθοδος επικοινωνίας μεταξύ διεργασιών διατηρείται σκόπιμα πολύ απλή: Η <classname>Plug</classname> γράφει το αναγνωριστικό της σε ένα αρχείο κειμένου με όνομα <filename>plug.id</filename> και η επεξεργασία με τον δέκτη διαβάζει το αναγνωριστικό από αυτό το αρχείο. Σε ένα πραγματικό πρόγραμμα, μπορεί να θέλετε να χρησιμοποιήσετε μια περισσότερο προηγμένη μέθοδο επικοινωνίας μεταξύ των διεργασιών.Το παρακάτω πρόγραμμα χρησιμοποιεί μία <classname>Gtk::AspectFrame</classname> για να παρουσιάσει μια περιοχή σχεδίασης της οποίας η αναλογία διαστάσεων θα είναι πάντα 2:1, ανεξάρτητα πώς ο χρήστης αυξομειώνει το παράθυρο κορυφαίου επιπέδου.Η συνάρτηση <methodname>Cairo::Context::arc_negative()</methodname> είναι ακριβώς η ίδια με την <methodname>Cairo::Context::arc()</methodname>, αλλά οι γωνίες πηγαίνουν προς την αντίθετη κατεύθυνση.Η συνάρτηση <methodname>Cairo::Context::paint()</methodname> χρησιμοποιείται εδώ για να ορίσει το χρώμα παρασκηνίου του παραθύρου. Αυτή η συνάρτηση δεν παίρνει ορίσματα και γεμίζει την τρέχουσα επιφάνεια (ή το αποκομμένο τμήμα της επιφάνειας) με το τρέχον ενεργό πηγαίο χρώμα. Μετά τον ορισμό του χρώματος παρασκηνίου του παραθύρου, σχεδιάζουμε έναν κύκλο για το περίγραμμα του ρολογιού, το γεμίζουμε με λευκό και έπειτα βάφουμε το περίγραμμα με μαύρο. Σημειώστε ότι και οι δυο αυτές ενέργειες χρησιμοποιούν την παραλλαγή <methodname>_preserve</methodname> για να διατηρήσουν το τρέχον μονοπάτι και έπειτα αυτό το ίδιο το μονοπάτι περικόπτεται για να διασφαλίσει ότι οι επόμενες γραμμές μας δεν θα πάνε έξω από το περίγραμμα του ρολογιού.Οι συναρτήσεις <methodname>move_item()</methodname>, <methodname>remove_item()</methodname> και <methodname>purge_items()</methodname> δεν επιδρούν στα ενεργά αρχεία που αναφέρονται από τα URIs, τροποποιούν μόνο τον κατάλογο των πρόσφατων αρχείων.Η ομάδα που θεωρεί τις τιμές ως τυχαίους αριθμούς περιλαμβάνει τα γραφικά συστατικά <classname>Range</classname> (<classname>Scrollbar</classname> και <classname>Scale</classname>), το γραφικό συστατικό <classname>ScaleButton</classname> και το γραφικό συστατικό <classname>SpinButton</classname>. Αυτά τα γραφικά συστατικά είναι τυπικά "προσαρμοσμένα" άμεσα από τον χρήστη με το ποντίκι ή το πληκτρολόγιο. Θα θεωρήσουν τις τιμές <parameter>lower</parameter> και <parameter>upper</parameter> μιας προσαρμογής ως μια περιοχή μέσα στην οποία ο χρήστης μπορεί να χειριστεί την <parameter>value</parameter> της προσαρμογής. Από προεπιλογή, θα τροποποιήσουν μόνο την <parameter>value</parameter> μιας προσαρμογής.Η υλοποίηση της μεθόδου <function>wrap_init()</function> στο <filename>wrap_init.cc</filename> δημιουργείται από το <filename>generate_wrap_init.pl</filename>, αλλά η δήλωση στο <filename>wrap_init.h</filename> είναι κωδικοποιημένη με το χέρι, έτσι θα χρειαστεί να ρυθμίσετε το <filename>wrap_init.h</filename> έτσι ώστε η συνάρτηση <function>wrap_init()</function> να εμφανίζεται στον σωστό χώρο ονόματος C++.Το κείμενο της ετικέτας μπορεί να στοιχιστεί χρησιμοποιώντας τη μέθοδο <methodname>set_justify()</methodname>. Το γραφικό συστατικό μπορεί επίσης να αναδιπλώσει λέξεις, που μπορεί να ενεργοποιηθεί με τη <methodname>set_line_wrap()</methodname>.Η τελευταία γραμμή εμφανίζει το παράθυρο και εισάγει τον κύριο βρόχο επεξεργασίας της <application>gtkmm</application>, που θα τελειώσει, όταν κλείσει το παράθυρο. Η συνάρτηση <function>main()</function>, θα επιστρέψει τότε με τον κατάλληλο κώδικα επιτυχίας ή σφάλματος.Η τεχνοτροπία ένωσης γραμμής ορίζεται χρησιμοποιώντας τη συνάρτηση <methodname>Cairo::Context::set_line_join()</methodname>.Η λίστα παρέχεται μέσα από <classname>TreeModel</classname> και οι στήλες από αυτό το πρότυπο προστίθενται στην προβολή του ComboBox με τη μέθοδο <methodname>ComboBox::pack_start()</methodname>. Αυτό παρέχει ευελιξία και ασφάλεια τύπου χρόνου μεταγλώττισης, αλλά η κλάση <classname>ComboBoxText</classname> παρέχει μια πιο απλή εξειδίκευση με βάση το κείμενο σε περίπτωση που η ευελιξία δεν απαιτείται.Οι μακροεντολές εξηγούνται πιο λεπτομερώς στις παρακάτω ενότητες.Οι μακροεντολές σε αυτό το παράδειγμα κάνει το εξής: <placeholder-1/>Οι μακροεντολές που χρησιμοποιείτε στα αρχεία .hg και .ccg χρειάζεται συχνά να ξέρουν πώς να μετατρέψετε έναν τύπο C++ σε έναν τύπο C, ή αντίστροφα. Η gmmproc παίρνει αυτήν την πληροφορία από ένα αρχείο .m4 στον κατάλογό σας <literal>tools/m4/</literal>. Αυτό επιτρέπει την κλήση μιας συνάρτησης C στην υλοποίηση της μεθόδου σας C++, περνώντας τις κατάλληλες παραμέτρους σε αυτήν την συνάρτηση C. Για παράδειγμα, αυτό λέει στην gmmproc πώς να μετατρέψει έναν δείκτη GtkTreeView σε έναν δείκτη Gtk::TreeView: <placeholder-1/>Η κύρια δραστηριότητα στην διεργασία διεθνοποίησης είναι η εύρεση των συμβολοσειρών που βλέπουν οι χρήστες και η σημείωσή τους για μετάφραση. Δεν χρειάζεστε να το κάνετε όλο μονομιάς - αν εγκαταστήσετε την απαραίτητη υποδομή του έργου σωστά, τότε η εφαρμογή σας θα δουλέψει κανονικά ανεξάρτητα από το πόσες συμβολοσειρές έχετε καλύψει.Η μέγιστη ηλικία των στοιχείων στον κατάλογο των πρόσφατα χρησιμοποιημένων αρχείων μπορεί να οριστεί με την <methodname>Gtk::Settings::property_gtk_recent_files_max_age()</methodname>. Προεπιλεγμένη τιμή: 30 ημέρες.Το πρότυποΤο πρότυπο για ένα ComboBox μπορεί να οριστεί και να συμπληρωθεί ακριβώς όπως μια <classname>TreeView</classname>. Για παράδειγμα, μπορείτε να παράξετε μια κλάση σύνθετου πλαισίου με έναν ακέραιο και μια στήλη κειμένου, ως εξής:Το όνομα της βιβλιοθήκης, όπως libsomethingmm.Τα ονόματα των πακέτων της <application>gtkmm</application> ποικίλουν από διανομή σε διανομή (π.χ. <application>libgtkmm3.0-dev</application> στο Ντέμπιαν και Ουμπούντου ή <application>gtkmm30-devel</application> στο Ρέντ χατ φεντόρα), γιαυτό ελέγξτε το πρόγραμμα διαχείρισης πακέτου της διανομής σας για το σωστό όνομα πακέτου και εγκαταστήστε το όπως θα κάνατε με οποιοδήποτε άλλο πακέτο.Ο εγγενής διάλογος εκτύπωσης GTK+ έχει ένα πλήκτρο προεπισκόπησης, αλλά μπορείτε επίσης να ξεκινήσετε μια προεπισκόπηση άμεσα από μια εφαρμογή: <placeholder-1/>Το επόμενο είναι πιο ενδιαφέρον. Η <function>sigc::mem_fun()</function> καλείται με δύο ορίσματα. Το πρώτο όρισμα είναι <parameter>some_object</parameter>, που είναι το αντικείμενο που η νέα μας υποδοχή θα δείχνει. Το δεύτερο όρισμα είναι ένας δείκτης σε μια από τις μεθόδους του. Αυτή η συγκεκριμένη έκδοση της <function>sigc::mem_fun()</function> δημιουργεί μια υποδοχή που, όταν "κληθεί", θα καλέσει τη μέθοδο στην οποία δείχνει του συγκεκριμένου αντικειμένου, σε αυτήν την περίπτωση στην <methodname>some_object.on_button_clicked()</methodname>.Η επόμενη πρόταση: <placeholder-1/> δημιουργεί ένα αντικείμενο <classname>Gtk::Application</classname>, αποθηκευμένο σε έναν έξυπνο δείκτη <classname>RefPtr</classname>. Αυτό χρειάζεται σε όλες τις εφαρμογές <application>gtkmm</application>. Η μέθοδος <methodname>create()</methodname> για αυτό το αντικείμενο αρχικοποιεί το <application>gtkmm</application> και ελέγχει τα ορίσματα που πέρασαν στην εφαρμογή σας στη γραμμή εντολών, κοιτώντας για τυπικές επιλογές όπως <literal>--display</literal>. Τις παίρνει από τη λίστα ορισμάτων, αφήνοντας οτιδήποτε δεν αναγνωρίζει για την εφαρμογή σας να αναλυθεί ή να αγνοηθεί. Αυτό διασφαλίζει ότι όλες οι εφαρμογές του <application>gtkmm</application> δέχονται το ίδιο σύνολο τυπικών ορισμάτων.Οι επόμενες δύο γραμμές κώδικα δημιουργούν ένα παράθυρο και ορίζουν το προεπιλεγμένο (αρχικό) μέγεθος τους:Ο αριθμός των δεκαδικών θέσεων μπορεί να αλλαχτεί χρησιμοποιώντας τη μέθοδο <methodname>set_digits()</methodname>.Η μόνη διαφορά μεταξύ αυτού του παραδείγματος και του παραδείγματος της ευθείας γραμμής είναι στη συνάρτηση <methodname>on_draw()</methodname>, αλλά υπάρχουν λίγες νέες έννοιες και συναρτήσεις που εισήχθησαν εδώ, έτσι ας τις εξετάσουμε συνοπτικά.Ο προσανατολισμός μιας <classname>Gtk::Scrollbar</classname> μπορεί να είναι ή οριζόντιος ή κάθετος.Η άλλη ομάδα περιλαμβάνει τα γραφικά συστατικά <classname>Viewport</classname> widget και <classname>ScrolledWindow</classname>. Όλα αυτά τα γραφικά συστατικά χρησιμοποιούν τιμές εικονοστοιχείου για τις προσαρμογές τους. Αυτά προσαρμόζονται επίσης τυπικά εμμέσως χρησιμοποιώντας γραμμές κύλισης. Ενώ όλα τα γραφικά συστατικά που χρησιμοποιούν προσαρμογές μπορούν ή να δημιουργήσουν τις δικές τους προσαρμογές ή να χρησιμοποιήσουν αυτές που δίνετε, θα θέλετε γενικά να επιτρέψετε σε αυτήν τη συγκεκριμένη κατηγορία γραφικών συστατικών να δημιουργήσει τις δικές της προσαρμογές.Τα ονόματα του πακέτου δεν θα αλλάζουν όταν νέες συμβατές εκδόσεις API/ABI της <application>gtkmm</application> κυκλοφορούν. Αλλιώς, μπορεί να μην είναι συμβατά με API/ABI. Έτσι μην εκπλαγείτε, για παράδειγμα, αν βρείτε τη <application>gtkmm</application> 3.8 που παρέχεται από το πακέτο <application>libgtkmm3.0-dev</application> του Ντέμπιαν.Το κύριο μειονέκτημα χρήσης γραφικών συστατικών εμβέλειας κλάσης είναι η εμφάνιση της υλοποίησης κλάσης αντί για την διεπαφή κλάσης στην κεφαλίδα κλάσης.Το κύριο αντικείμενο είναι <classname>Gtk::PrintOperation</classname>, κατανεμημένο για κάθε λειτουργία εκτύπωσης. Για χειρισμό της σχεδίασης σελίδας συνδεθείτε με τα σήματά του, ή κληρονομείστε από αυτό και αντικαταστήστε τους προεπιλεγμένους εικονικούς χειριστές σήματος. Η <classname>PrintOperation</classname> χειρίζεται αυτόματα όλες τις ρυθμίσεις που επηρεάζουν τον βρόχο εκτύπωσης.Η διαδικασία συγγραφής πηγαίου κώδικα που επιτρέπει την μετάφραση λέγεται <literal>διεθνοποίηση</literal>, συχνά συντομεύεται σε <literal>i18n</literal>. Η διεργασία <literal>τοπικοποίηση</literal>, μερικές φορές συντομευμένη ως <literal>l10n</literal>, παρέχει μεταφρασμένο κείμενο για άλλες γλώσσες, με βάση αυτόν τον πηγαίο κώδικα.Η γραμμή προόδου μπορεί επίσης να εμφανίσει μια ρυθμίσιμη συμβολοσειρά κειμένου μέσα στην υποδοχή, χρησιμοποιώντας τη μέθοδο <methodname>set_text()</methodname>.Ο σκοπός αυτού του παραδείγματος είναι να εμφανίσει τα βήματα που παίρνει το συμβάν όταν εκπέμπεται.Η τιμή επιστροφής είναι μια <classname>sigc::connection</classname> που μπορεί να χρησιμοποιηθεί για να σταματήσει την παρακολούθηση αυτού του περιγραφέα αρχείου χρησιμοποιώντας τη μέθοδό του <methodname>disconnect()</methodname>. Ο χειριστής σήματος <parameter>slot</parameter> πρέπει να δηλωθεί ως εξής:Οι κανόνεςΟι ίδιες αρχές εφαρμόζονται για σήματα που έχουν περισσότερα ορίσματα. Ιδού ένα με τρία (ελήφθησαν από <filename>&lt;gtkmm/textbuffer.h&gt;</filename>):Ο δεύτερος τρόπος να ρυθμίσετε τα ραδιοπλήκτρα είναι να κάνετε πρώτα μια ομάδα και έπειτα να προσθέσετε ραδιοπλήκτρα σε αυτή. Ιδού ένα παράδειγμα:Η ενότητα για σχεδίαση ενός τόξου εισάγει μια νέα συνάρτηση, <methodname>close_path()</methodname>. Αυτή η συνάρτηση θα σχεδιάσει στην πραγματικότητα μια ευθεία γραμμή από το τρέχον σημείο πίσω προς το πρώτο σημείο στη διαδρομή. Υπάρχει μια σημαντική διαφορά μεταξύ κλήσης της <methodname>close_path()</methodname> και χειροκίνητης σχεδίασης μιας γραμμής πίσω προς το αρχικό σημείο, όμως. Αν χρησιμοποιήσετε την <methodname>close_path()</methodname>, οι γραμμές θα ενωθούν ωραία μαζί. Αν χρησιμοποιήσετε την <methodname>line_to()</methodname>, οι γραμμές θα τερματίσουν στο ίδιο σημείο, αλλά το Cairo δεν θα κάνει καμιά ειδική ένωση.Οι επιλεγμένες γραμμέςΟ χειριστής σήματος είναι <methodname>on_button_clicked()</methodname>.Τα γραφικά συστατικά περιέκτη μοναδικού στοιχείου παράγονται από <classname>Gtk::Bin</classname>, που παρέχει τις μεθόδους <methodname>add()</methodname> και <methodname>remove()</methodname> για το θυγατρικό γραφικό συστατικό. Σημειώστε ότι, οι <classname>Gtk::Button</classname> και <classname>Gtk::Window</classname> είναι τεχνικά περιέκτες μοναδικού στοιχείου, αλλά το έχουμε ήδη συζητήσει αλλού.Οι συνδεμένες υποδοχές με αντικείμενα <classname>sigc::signal</classname> εκτελούν στο νήμα όποιες κλήσεις <methodname>emit()</methodname> ή <methodname>operator()()</methodname> στο σήμα. Η <classname>Glib::Dispatcher</classname> δεν συμπεριφέρεται ίδια: εκτελεί τις συνδεμένες υποδοχές της στο νήμα στο οποίο το αντικείμενο <classname>Glib::Dispatcher</classname> δομήθηκε (που πρέπει να έχει έναν κύριο βρόχο glib). Αν ένα αντικείμενο <classname>Glib::Dispatcher</classname> δομείται στο κύριο νήμα γραφικής διεπαφής χρήστη (που θα είναι συνεπώς το νήμα του δέκτη), οποιοδήποτε νήμα εργασίας μπορεί να το εκπέμψει και να έχει εκτελέσει με ασφάλεια τις συνδεμένες υποδοχές των συναρτήσεων <application>gtkmm</application>.Το πηγαίο γραφικό συστατικό θα εκπέμψει αυτά τα σήματα, με αυτήν τη σειρά: <placeholder-1/>Τα τυπικά πρότυπα δένδρου (<classname>TreeStore</classname> και <classname>ListStore</classname>) παράγονται από <classname>TreeSortable</classname>, έτσι προσφέρουν ταξινόμηση λειτουργικότητας. Για παράδειγμα, καλέστε <methodname>set_sort_column()</methodname>, για ταξινόμηση του προτύπου από τη συγκεκριμένη στήλη. Ή δώστε μια συνάρτηση επανάκλησης <methodname>set_sort_func()</methodname> για να υλοποιηθεί ένας πιο περίπλοκος αλγόριθμος ταξινόμησης.Η στήλη κειμένουΤο τέχνασμα είναι η τοποθέτηση στη μέση του εικονοστοιχείου όπου θέλετε η γραμμή να σχεδιαστεί και έτσι εγγυάται ότι παίρνετε τα επιθυμητά αποτελέσματα. Δείτε <ulink url="http://cairographics.org/FAQ/#sharp_lines">Συχνές ερωτήσεις Cairo</ulink>.Η χρήση της λέξης-κλειδί <literal>const</literal> στην C++ δεν είναι πάντα σαφής. Μπορεί να μην καταλάβετε ότι ο <type>const Something*</type> δηλώνει έναν δείκτη σε έναν <type>const Something</type>. Ο δείκτης μπορεί να αλλαχθεί, αλλά όχι ο <type>Something</type> στον οποίο δείχνει.Η τιμή μπορεί να έχει έναν ρυθμίσιμο αριθμό δεκαδικών θέσεων και το βήμα του μεγέθους είναι διαμορφώσιμο. Οι <classname>SpinButton</classname>s έχουν ένα γνώρισμα 'αυτόματης επανάληψης' επίσης: κρατώντας πατημένο το κουμπί αύξησης ή μείωσης μπορεί προαιρετικά να προκαλέσει μια πιο γρήγορη αλλαγή της τιμής όσο το κουμπί κρατιέται πατημένο.Η εμφανιζόμενη τιμή από ένα γραφικό συστατικό κλίμακας στρογγυλοποιείται σε μια δεκαδική θέση από προεπιλογή, όπως είναι το πεδίο <literal>value</literal> στο <classname>Gtk::Adjustment</classname>. Μπορείτε να το αλλάξετε με τη μέθοδο <methodname>set_digits()</methodname>.Η εικονική μέθοδος <methodname>on_draw()</methodname> παρέχει ένα περιεχόμενο Cairo που θα χρησιμοποιήσετε για σχεδίαση στο γραφικό συστατικό <classname>Gtk::DrawingArea</classname>. Δεν είναι απαραίτητο να αποθηκεύσετε και να επαναφέρετε αυτό το περιεχόμενο Cairo στην <methodname>on_draw()</methodname>.Ο τρόπος που δουλεύει είναι ότι στέλνετε τον πηγαίο κώδικα σας σε ένα αποθετήριο git, όπου οι μεταφραστές μπορούν να το προσπελάσουν, έπειτα επικοινωνείτε με την ταχυδρομική λίστα του gnome-i18n και ζητάτε να προστεθεί το πρόγραμμά σας στο <ulink url="http://l10n.gnome.org/module/">Κατάλογος ενοτήτων για μετάφραση</ulink>.Ο τρόπος που οι <classname>Sockets</classname> και <classname>Plugs</classname> δουλεύουν μαζί είναι μέσα από τα αναγνωριστικά του παραθύρου τους. Και οι δυο <classname>Socket</classname> και <classname>Plug</classname> έχουν αναγνωριστικά που μπορούν να ανακτηθούν με τις συναρτήσεις μέλους τους <methodname>get_id()</methodname>. Η χρήση αυτών των αναγνωριστικών θα εξηγηθεί παρακάτω στο <xref linkend="sec-connecting-plugs-sockets"/>.Τα γραφικά συστατικά δεν αναδιατάσσουν τους εαυτούς τους όταν το παράθυρο αυξομειώνεται. Κάποια γραφικά συστατικά κρύβονται όταν το παράθυρο γίνεται μικρότερο και πολύς άχρηστος χώρος εμφανίζεται όταν το παράθυρο γίνεται μεγαλύτερο.Το πλάτος της ετικέτας θα προσαρμοστεί αυτόματα. Μπορείτε να παράξετε ετικέτες πολλαπλών γραμμών βάζοντας αλλαγές γραμμών ("\n") στη συμβολοσειρά της ετικέτας.Το αναγνωριστικό του παραθύρου είναι: 69206019Έπειτα επεξεργαστείτε το αρχείο <filename>.cc</filename> για να ορίσετε τους σωστούς τύπους. Για παράδειγμα, η συνάρτησή σας <function>main()</function> μπορεί να μοιάζει ως εξής: <placeholder-1/>Έπειτα αρχίστε το πρόγραμμα <filename>socket</filename>:Έπειτα χρησιμοποιήστε την <methodname>append_column()</methodname> για να προσθέσετε τη στήλη προβολής στην προβολή. Σημειώστε ότι η <methodname>Gtk::TreeView::append_column()</methodname> επικαλύπτεται για να δεχτεί είτε ένα προκατασκευασμένο γραφικό συστατικό <classname>Gtk::TreeView::Column</classname>, ή απλά την <classname>TreeModelColumn</classname> από την οποία παράγει ένα κατάλληλο γραφικό συστατικό <classname>Gtk::TreeView::Column</classname>.Έπειτα επιβεβαιώνετε την ενημέρωση του αρχείου <filename>POTFILES.in</filename> στον υποκατάλογο <filename>po/</filename> (η <command>intltool-update -M</command> μπορεί να βοηθήσει) έτσι ώστε οι μεταφραστές να προσπελάζουν πάντα ενημερωμένα αρχεία <filename>myprogram.pot</filename> και να παγώνουν απλά τις συμβολοσειρές τουλάχιστον λίγες ημέρες πριν να κάνετε μια νέα έκδοση, ανακοινώντας την στο gnome-i18n. Ανάλογα με τον αριθμό των συμβολοσειρών που το πρόγραμμά σας περιέχει και το πόσο δημοφιλές είναι, οι μεταφράσεις θα αρχίσουν τότε να σημειώνονται σε αρχεία <filename>languagename.po</filename>.Έπειτα, για να προσθέσετε ένα γραφικό συστατικό σε αυτή τη θέση, χρησιμοποιήστε <methodname>Gtk::TextView::add_child_at_anchor()</methodname>:Έπειτα, μπορείτε να ορίσετε την ενεργή ορατή διάταξη των μενού και εργαλειοθηκών και να προσθέσετε τη διάταξη γραφικής διεπαφής στην <classname>UIManager</classname>. Αυτή η "συμβολοσειρά γραφικής διεπαφής" χρησιμοποιεί μια μορφή XML, στην οποία θα πρέπει να αναφέρετε τα ονόματα των ενεργειών που έχετε ήδη δημιουργήσει. Για παράδειγμα:Υπάρχουν κάποια πράγματα να σημειώσετε για αυτόν τον κώδικα του παραδείγματος. Πάλι, η μόνη πραγματική διαφορά μεταξύ αυτού του παραδείγματος και των προηγούμενων είναι η συνάρτηση <methodname>on_draw()</methodname>, έτσι θα περιορίσουμε την εστίασή μας σε αυτήν τη συνάρτηση. Επιπλέον, το πρώτο μέρος της συνάρτησης είναι σχεδόν ταυτόσημο με τα προηγούμενα παραδείγματα, έτσι θα παραλείψουμε αυτό το τμήμα.Υπάρχουν λίγα συνηθισμένα λάθη που πρέπει να βρείτε τελικά οι ίδιοι. Αλλά αυτή η ενότητα μπορεί να σας βοηθήσει να τα αποφύγετε.Υπάρχει ένας αριθμός από μεταβλητές κατάστασης γραφικών που μπορεί να οριστεί για περιεχόμενο Cairo. Τα πιο κοινά γνωρίσματα περιεχομένου είναι χρώμα (χρησιμοποιώντας <methodname>set_source_rgb()</methodname> ή <methodname>set_source_rgba()</methodname> για ημιδιαφανή χρώματα), πλάτος γραμμής (χρησιμοποιώντας <methodname>set_line_width()</methodname>), μοτίβο παύλας γραμμής (χρησιμοποιώντας <methodname>set_dash()</methodname>), τεχνοτροπία άκρου γραμμής (χρησιμοποιώντας <methodname>set_line_cap()</methodname>), και τεχνοτροπία ένωσης γραμμών (χρησιμοποιώντας <methodname>set_line_join()</methodname>), και τεχνοτροπίες γραμματοσειρών (χρησιμοποιώντας <methodname>set_font_size()</methodname>, <methodname>set_font_face()</methodname> και άλλες). Υπάρχουν επίσης πολλές άλλες ρυθμίσεις, όπως πίνακες μετασχηματισμών, γέμισμα κανόνων, αν θα εκτελεστεί εξομάλυνση κι άλλες. Για περισσότερες πληροφορίες, δείτε την τεκμηρίωση API <ulink url="http://www.cairographics.org/cairomm/">cairomm</ulink>.Υπάρχουν βασικά πέντε διαφορετικές τεχνοτροπίες, όπως φαίνεται σε αυτήν την εικόνα:Υπάρχουν άλλα πράγματα που μπορείτε να προσαρμόσετε επίσης, συμπεριλαμβανομένων της δημιουργίας γραμμών με παύλες και άλλα. Για περισσότερες πληροφορίες, δείτε την τεκμηρίωση API Cairo.Υπάρχουν αρκετές παραγόμενες κλάσεις <classname>Dialog</classname> που μπορεί να βρείτε χρήσιμες. Η <classname>Gtk::MessageDialog</classname> χρησιμοποιείται για τις πιο απλές ειδοποιήσεις. Αλλά άλλες φορές μπορεί να χρειαστείτε να παράξετε τη δική σας κλάση διαλόγου για να δώσετε περισσότερο σύνθετη λειτουργικότητα.Υπάρχουν αρκετές επιλογές που διέπουν τον τρόπο συσκευασίας των γραφικών συστατικών και αυτό μπορεί να μπερδεύει στην αρχή. Αν δυσκολεύεστε, τότε είναι μερικές φορές καλή ιδέα να παίξετε με τον σχεδιαστή γραφικής διεπαφής <application>glade</application> για να δείτε τι είναι δυνατό. Μπορείτε ακόμα να αποφασίσετε τη χρήση της API <application>Gtk::Builder</application> για τη φόρτωση της γραφικής διεπαφής κατά τον χρόνο εκτέλεσης.Υπάρχουν αρκετοί άλλοι περιέκτες, που θα συζητήσουμε επίσης.Υπάρχουν κάποια προαιρετικά πρόσθετα ορίσματα: <placeholder-1/>Υπάρχουν ειδικές APIs για μενού και εργαλειοθήκες, αλλά θα πρέπει συνήθως να τις αντιμετωπίσετε μαζί, χρησιμοποιώντας την <classname>UIManager</classname> για να ορίσετε τις <classname>Action</classname>s που μπορείτε έπειτα να ταξινομήσετε στα μενού και τις εργαλειοθήκες. Με αυτόν τον τρόπο μπορείτε να χειριστείτε την ενεργοποίηση της ενέργειας αντί να απαντήσετε στα στοιχεία μενού και εργαλειοθήκης ξεχωριστά. Και μπορείτε να ενεργοποιήσετε ή να απενεργοποιήσετε και τα δυο στοιχεία μενού και εργαλειοθήκης μέσα από την ενέργεια.Υπάρχουν δύο βασικές στρατηγικές που μπορούν να χρησιμοποιηθούν: <placeholder-1/>Υπάρχουν δύο ενσωματωμένες <classname>Mark</classname>s - <literal>insert</literal> και <literal>select_bound</literal>, που μπορείτε να προσπελάσετε στην <classname>TextBuffer</classname> με τις μεθόδους <methodname>get_insert()</methodname> και <methodname>get_selection_bound()</methodname>.Υπάρχουν δύο τρόποι δημιουργίας ενός κουμπιού. Μπορείτε να ορίσετε μια συμβολοσειρά ετικέτας στον κατασκευαστή <classname>Gtk::Button</classname>, ή να το ορίσετε αργότερα με <methodname>set_label()</methodname>.Υπάρχουν δύο τρόποι να ρυθμίσετε μια ομάδα ραδιοπλήκτρων. Ο πρώτος τρόπος είναι η δημιουργία κουμπιών και η ρύθμιση των ομάδων τους κατόπιν. Μόνο οι πρώτοι δύο κατασκευαστές χρησιμοποιούνται. Στο παρακάτω παράδειγμα, κάνουμε μια νέα κλάση παραθύρων που λέγεται <classname>RadioButtons</classname> και έπειτα βάζουμε τρία ραδιοπλήκτρα μέσα της:Υπάρχει μια μέθοδος για σχεδίαση από μια <classname>Gdk::Pixbuf</classname> σε μια <classname>Cairo::Context</classname>. Μια ενδιάμεση μνήμη <classname>Gdk::Pixbuf</classname> είναι ένας χρήσιμος συσκευαστής γύρω από μια συλλογή εικονοστοιχείων, που μπορεί να διαβαστεί από αρχεία και χειρίζεται με ποικίλους τρόπους.Υπάρχει ένα πιο σύνθετο παράδειγμα στο examples/others/dnd.Υπάρχει ένα προαιρετικό πρόσθετο όρισμα: <placeholder-1/>Εκεί μπορεί να υπάρχουν φορές που χρειάζεστε να τροποποιήσετε τον κατάλογο των πρόσφατων αρχείων. Για παράδειγμα, αν ένα αρχείο μετακινήθηκε ή μετονομάστηκε, μπορεί να χρειαστεί να ενημερώσετε τη θέση του αρχείου στον κατάλογο πρόσφατων αρχείων, έτσι ώστε να μην δείχνει μια εσφαλμένη θέση. Μπορείτε να ενημερώσετε τη θέση ενός στοιχείου χρησιμοποιώντας την <methodname>move_item()</methodname>.Υπάρχουν μάλλον πολλά να σκεφτείτε για αυτόν τον (μη λειτουργικό) κώδικα. Πρώτα ας αναγνωρίσουμε τα εμπλεκόμενα μέρη:Συνεπώς, η ισοδύναμη <classname>RefPtr</classname> του <type>Something*</type> για μια παράμετρο μεθόδου είναι <type>const Glib::RefPtr&lt;Something&gt;&amp;</type> και ο ισοδύναμος του <type>const Something*</type> είναι <type>const Glib::RefPtr&lt;const Something&gt;&amp;</type>.Αυτές είναι τυπικές γραμμές κύλισης. Πρέπει να χρησιμοποιηθούν μόνο για κύλιση ενός άλλου γραφικού συστατικού, όπως, <classname>Gtk::Entry</classname>, ή <classname>Gtk::Viewport</classname>, αν και είναι συνήθως ευκολότερη η χρήση του γραφικού συστατικού <classname>Gtk::ScrolledWindow</classname> στις περισσότερες περιπτώσεις.Αυτές οι εξαρτήσεις έχουν τις δικές τους εξαρτήσεις, συμπεριλαμβανόμενων των ακόλουθων εφαρμογών και βιβλιοθηκών:Αυτές οι αλληλεπιδράσεις εγείρονται από το γεγονός ότι, μεταξύ άλλων πραγμάτων, μια κλάση που κληρονομεί από την <classname>sigc::trackable</classname> θα έχει, μέσα από αυτήν την κληρονομικότητα, ένα αντικείμενο <classname>std::list</classname> που παρακολουθεί τις υποδοχές που δημιουργήθηκαν από κλήσεις στη <function>sigc::mem_fun()</function> που αντιστοιχεί σε οποιαδήποτε από τις μη στατικές μεθόδους (πιο ειδικά κρατά έναν κατάλογο επανακλήσεων που θα μηδενίσει τις συνδεμένες υποδοχές στην καταστροφή της). Κάθε αντικείμενο <classname>sigc::slot</classname> κρατά επίσης, μέσα από την <classname>sigc::slot_rep</classname>, το δικό της αντικείμενο <classname>sigc::trackable</classname> για να ανιχνεύει οποιαδήποτε αντικείμενα <classname>sigc::connection</classname> που χρειάζεται για να πληροφορήσει για το θάνατό της και έχει επίσης μια συνάρτηση κατάργησης καταχώρισης του εαυτού της από οποιαδήποτε <classname>sigc::trackable</classname> κατά την αποσύνδεση ή καταστροφή. Τα αντικείμενα <classname>sigc::signal</classname> κρατούν επίσης καταλόγους υποδοχών, που θα ενημερωθούν με μια κλήση στη μέθοδό τους <methodname>connect()</methodname> ή κλήσεις σε οποιοδήποτε αντικείμενο <classname>sigc::connection</classname> που αναφέρεται σε μια τέτοια σύνδεση.Αυτά τα σήματα συμπεριφέρονται λίγο διαφορετικά. Η επιστρεφόμενη τιμή από τον χειριστή σήματος δείχνει αν έχει "χειριστεί" πλήρως το συμβάν. Αν η τιμή είναι <literal>false</literal> τότε η <application>gtkmm</application> θα περάσει το συμβάν στον επόμενο χειριστή σήματος. Αν η τιμή είναι <literal>true</literal>, τότε κανένας άλλος χειριστής σήματος δεν θα χρειαστεί να κληθεί.Αυτά τα γραφικά συστατικά χρησιμοποιούνται κυρίως για διάκοσμο ή διάταξη, έτσι δεν θα χρειάζεστε συχνά τη σύλληψη συμβάντων σε αυτά. Προορίζονται να μην έχουν X-Window για να βελτιώσουν την απόδοση.Τα πράγματα μεταφέρονται από <literal>πηγές</literal> για να αποτεθούν σε <literal>προορισμούς</literal>. Κάθε πηγή και προορισμός έχει πληροφορίες για τις μορφές δεδομένων που μπορεί να στείλει ή να δεχτεί, που παρέχονται από τα στοιχεία <classname>Gtk::TargetEntry</classname>. Ένας προορισμός απόθεσης θα δεχτεί μόνο ένα μεταφερόμενο στοιχείο αν και οι δυο μοιράζονται ένα συμβατό στοιχείο <classname>Gtk::TargetEntry</classname>. Κατάλληλα σήματα θα εκπεμφθούν τότε, λέγοντας στους χειριστές σήματος ποια <classname>Gtk::TargetEntry</classname>.Αυτό το αρχείο <filename>.defs</filename> περιγράφει τύπους απαρίθμησης και τις πιθανές τιμές τους. Δημιουργείται από το σενάριο <filename>enum.pl</filename> που μπορείτε να βρείτε στον κατάλογο <filename>tools</filename> του glibmm. Για παράδειγμα, <placeholder-1/>Αυτό το αρχείο <filename>.defs</filename> περιγράφει αντικείμενα και τις συναρτήσεις τους. Δημιουργείται από το σενάριο <command>h2def.py</command> που μπορείτε να βρείτε στον κατάλογο <filename>tools/defs_gen</filename>. Για παράδειγμα, <placeholder-1/>Αυτό το αρχείο <filename>.defs</filename> περιγράφει σήματα και ιδιότητες. Δημιουργείται από το ειδικό εργαλείο <filename>generate_extra_defs</filename> που είναι σε κάθε έργο συσκευασίας, όπως <filename>gtkmm/tools/extra_defs_gen/</filename>. Για παράδειγμα <placeholder-1/>Αυτό το αρχείο <filename>.defs</filename> περιγράφει εικονικές συναρτήσεις (vfuncs). Πρέπει να γραφτεί με το χέρι. Δεν υπάρχει αρχείο σκελετού <filename>skeleton/src/skeleton_vfunc.defs</filename> για να ξεκινήσετε. Μπορείτε να κοιτάξετε επίσης στην <application>gtkmm</application> και στο αρχείο της <filename>gtk/src/gtk_vfuncs.defs</filename>.Αυτή η μεταβλητή <varname>PROGRAMNAME_LOCALEDIR</varname> θα χρησιμοποιηθεί αργότερα στο αρχείο <literal>Makefile.am</literal>, για να ορίσει μια μακροεντολή που θα χρησιμοποιηθεί όταν αρχικοποιήσετε την <application>gettext</application> στον πηγαίο κώδικά σας.Αυτό επιτρέπει στους συνδυασμούς γλωσσών να υλοποιήσουν τα δικά τους ισοδύναμα (όπως κατασκευαστές C++), χωρίς τη χρήση της συνάρτησης <function>*_new()</function>. Αυτό είναι συχνά απαραίτητο, έτσι ώστε να μπορούν στην πραγματικότητα να δημιουργήσουν μια παράγωγη GType, για να προσθέσουν τα δικά τους άγκιστρα για τους χειριστές σήματος και τις εικονικές συναρτήσεις (vfuncs).Αυτό το βιβλίοΑυτό το βιβλίο υποθέτει καλή κατανόηση της C++ και πώς να δημιουργείτε προγράμματα C++.Αυτό το βιβλίο εξηγεί βασικές έννοιες του <application>gtkmm</application> C++ API για δημιουργία διεπαφών χρήστη. Εισάγει επίσης τα κύρια στοιχεία διεπαφής χρήστη ("γραφικά συστατικά").Αυτό το βιβλίο εξηγεί βασικές έννοιες του <application>gtkmm</application> C++ API για δημιουργία διεπαφών χρήστη. Εισάγει επίσης τα κύρια στοιχεία διεπαφής χρήστη ("γραφικά συστατικά"). Αν και αναφέρει κλάσεις, κατασκευαστές και μεθόδους, δεν υπεισέρχεται σε πολύ λεπτομερώς. Συνεπώς, για πλήρεις πληροφορίες API, θα πρέπει να ακολουθήσετε τους συνδέσμους στην τεκμηρίωση αναφοράς.Αυτό προκαλεί την <application>gtkmm</application> να καλέσει τη συγκεκριμένη μέθοδο όποτε τίποτα άλλο δεν συμβαίνει. Μπορείτε να προσθέσετε μια προτεραιότητα (μικρότεροι αριθμοί έχουν μεγαλύτερη προτεραιότητα). Υπάρχουν δύο τρόποι για να αφαιρέσετε τον χειριστή σήματος: κλήση της <methodname>disconnect()</methodname> στο αντικείμενο <classname>sigc::connection</classname>, ή επιστροφή της <literal>false</literal> στον χειριστή σήματος, που πρέπει να δηλωθεί ως εξής:Αυτό το κεφάλαιο θα εισάγει μερικές από τις πιο σημαντικές πτυχές της κωδικοποίησης της <application>gtkmm</application>. Αυτές θα παρουσιαστούν με απλό παράδειγμα εργασίας κώδικα. Όμως, αυτό είναι απλά μια δοκιμή, έτσι χρειάζεται να κοιτάξετε τα άλλα κεφάλαια για περισσότερο ουσιαστικές πληροφορίες.Αυτή η κλάση υλοποιεί το παράθυρο "Hello World". Παράγεται από τη <classname>Gtk::Window</classname> και έχει ένα μοναδικό <classname>Gtk::Button</classname> ως μέλος. Έχουμε επιλέξει να χρησιμοποιήσουμε τον κατασκευαστή για να κάνει όλη την εργασία αρχικοποίησης για το παράθυρο, συμπεριλαμβανόμενης της ρύθμισης των σημάτων. Να το, με παράλειψη των σχολίων:Αυτή η εντολή θα δομήσει και θα εγκαταστήσει μια σειρά ενοτήτων και θα πάρει προφανώς αρκετά την πρώτη φορά για να ολοκληρωθεί. Μετά την πρώτη φορά, όμως, θα πρέπει να πάτε λίγο γρηγορότερα, αφού χρειάζεται μόνο να αναδομήσετε τα αρχεία που αλλάξατε από την τελευταία δόμηση. Εναλλακτικά, αφού έχετε δομήσει και εγκαταστήσει την <application>gtkmm</application> την πρώτη φορά, μπορείτε να αναδομήσετε την <application>gtkmm</application> από μόνη της (χωρίς αναδόμηση όλων των εξαρτήσεων της) με την εντολή <command>jhbuild buildone gtkmm</command>.Αυτό το σφάλμα μεταγλωττιστή μπορεί να μοιάζει ως εξής: <placeholder-1/> ή έτσι: <placeholder-2/>Αυτό το έγγραφο, όπως πολύ άλλο μεγάλο λογισμικό εκεί, δημιουργήθηκε δωρεάν από εθελοντές. Αν έχετε γνώσεις για οποιαδήποτε όψη της <application>gtkmm</application> που δεν έχει ήδη τεκμηριωθεί, παρακαλούμε να σκεφτείτε τη συνεισφορά του σε αυτό το έγγραφο.Αυτό το παράδειγμα προσθέτει μια <classname>ToolPalette</classname> και μια <classname>DrawingArea</classname> σε ένα παράθυρο και επιτρέπει στον χρήστη να μεταφέρει εικονίδια από την παλέτα εργαλείων στην περιοχή σχεδίασης. Η παλέτα εργαλείων περιέχει αρκετές ομάδες στοιχείων. Τα σύνθετα πλαίσια επιτρέπουν στον χρήστη να αλλάξει την τεχνοτροπία και τον προσανατολισμό της παλέτας εργαλείων.Αυτό το παράδειγμα επιτρέπει αντιγραφή και επικόλληση των ειδικών δεδομένων εφαρμογής, χρησιμοποιώντας τον τυπικό προορισμό κειμένου. Αν και είναι απλό, δεν είναι ιδανικό επειδή δεν αναγνωρίζει ότι τα δεδομένα <classname>Clipboard</classname> δεν είναι ειδικού τύπου.Αυτό το παράδειγμα δημιουργεί μια <classname>Gtk::EntryCompletion</classname> και την συσχετίζει με ένα γραφικό συστατικό <classname>Gtk::Entry</classname>. Η συμπλήρωση χρησιμοποιεί μια <classname>Gtk::TreeModel</classname> των πιθανών καταχωρίσεων και κάποιες πρόσθετες ενέργειες.Αυτό το παράδειγμα δημιουργεί ένα κουμπί με μια εικόνα και μια ετικέτα.Αυτό το παράδειγμα δημιουργεί ένα παράθυρο με τρία κουμπιά σε ένα πλέγμα. Τα πρώτα δύο κουμπιά είναι στην ανώτερη γραμμή, από αριστερά προς τα δεξιά. Ένα τρίτο κουμπί προσαρτάται κάτω από το πρώτο κουμπί, σε μια χαμηλότερη γραμμή, καλύπτοντας δύο στήλες.Αυτό το παράδειγμα δημιουργεί δύο εκτελέσιμα προγράμματα: <filename>socket</filename> και <filename>plug</filename>. Η ιδέα είναι ότι η <filename>socket</filename> έχει ένα παράθυρο εφαρμογής που θα ενσωματώσει ένα γραφικό συστατικό από το πρόγραμμα <filename>plug</filename>. Ο τρόπος αυτού του παραδείγματος σχεδιάστηκε έτσι ώστε το <filename>plug</filename> να πρέπει να εκτελεστεί πρώτα πριν ξεκινήσει το <filename>socket</filename>. Για να δείτε το παράδειγμα σε δράση, εκτελέστε τις παρακάτω εντολές με τη σειρά μέσα στον κατάλογο του παραδείγματος:Αυτό το παράδειγμα εμφανίζει ένα παράθυρο με τρία γραφικά συστατικά περιοχής που όλα είναι συνδεμένα με την ίδια ρύθμιση, μαζί με λίγα στοιχεία ελέγχου για ρύθμιση κάποιων παραμέτρων που αναφέρθηκαν παραπάνω και στην ενότητα των ρυθμίσεων, έτσι μπορείτε να δείτε πώς επηρεάζουν τον τρόπο εργασίας αυτά τα γραφικά συστατικά για τον χρήστη.Αυτό το παράδειγμα έχει ένα γραφικό συστατικό <classname>Gtk::TreeView</classname>, με ένα μοντέλο <classname>Gtk::ListStore</classname>.Αυτό το παράδειγμα υλοποιεί έναν περιέκτη με δύο θυγατρικά γραφικά συστατικά, το ένα πάνω από το άλλο. Φυσικά, σε αυτήν την περίπτωση μπορεί να είναι πολύ πιο απλά να χρησιμοποιήσετε απλά μια κάθετη <classname>Gtk::Box</classname>.Αυτό το παράδειγμα υλοποιεί ένα γραφικό συστατικό που σχεδιάζει ένα τρίγωνο Penrose.Αυτό το παράδειγμα είναι ταυτόσημο με το παράδειγμα <classname>ListStore</classname>, αλλά χρησιμοποιεί την <methodname>TreeView::append_column_editable()</methodname> αντί για <methodname>TreeView::append_column()</methodname>.Αυτό το παράδειγμα μοιάζει πολύ με το παράδειγμα <classname>ListStore</classname>, αλλά παράγει μια προσαρμοσμένη <classname>TreeView</classname> για να επικαλύψει το <literal>button_press_event</literal> και επίσης να ενθυλακώσει τον κώδικα προτύπου δένδρου στην παραγόμενη κλάση μας. Δείτε την ενότητα <link linkend="sec-treeview-contextmenu">Αναδυόμενο μενού περιεχομένων προβολής δένδρου</link>.Αυτό το παράδειγμα μοιάζει πολύ με το παράδειγμα <classname>TreeStore</classname>, αλλά έχει 2 πρόσθετες στήλες για να δείξει αν η γραμμή μπορεί να μετακινηθεί και αν μπορεί να δεχτεί γραμμές με μεταφορά και απόθεση. Χρησιμοποιεί μια παραγόμενη <classname>Gtk::TreeStore</classname> που υπερισχύει των εικονικών συναρτήσεων όπως περιγράφτηκαν στην ενότητα <link linkend="sec-treeview-draganddrop">Μεταφορά και απόθεση προβολής δένδρου</link>.Αυτό το παράδειγμα είναι πολύ παρόμοιο με το παράδειγμα <classname>ListStore</classname>, αλλά χρησιμοποιεί ένα μοντέλο <classname>Gtk::TreeStore</classname> και προσθέτει θυγατρικά στις γραμμές.Αυτό το παράδειγμα δείχνει λίγο τη διαφορά των μεθόδων αδράνειας και λήξης χρόνου. Αν χρειάζεστε μεθόδους που καλούνται περιοδικά και η ταχύτητα δεν είναι πολύ σημαντική, τότε θέλετε μεθόδους χρόνου λήξης. Αν θέλετε μεθόδους που καλούνται όσον το δυνατό πιο συχνά (όπως υπολογισμός κλαστικού στο παρασκήνιο), τότε χρησιμοποιήστε τις αδρανείς μεθόδους.Αυτό το παράδειγμα στοιχίζει δεξιά ένα κουμπί σε ένα παράθυρο χρησιμοποιώντας ένα γραφικό συστατικό <classname>Alignment</classname>.Αυτό το παράδειγμα δείχνει ένα γραφικό συστατικό <classname>Gtk::Entry</classname> με ένα επώνυμο εικονίδιο αναζήτησης και εκτυπώνει το κείμενο στο τερματικό, όταν το εικονίδιο πατιέται.Αυτό το παράδειγμα δείχνει ένα γραφικό συστατικό <classname>Gtk::Entry</classname> με μια γραμμή προόδου.Αυτό το παράδειγμα εμφανίζει πώς να φορτώσετε ένα αρχείο <application>Glade</application> στον χρόνο εκτέλεσης και να πώς να προσπελάσετε τα γραφικά συστατικά μέσα από μια παράγωγη κλάση.Αυτό το παράδειγμα χρησιμοποιεί την <classname>Gtk::Entry</classname>. Έχει επίσης δύο <classname>CheckButton</classname>s, με τα οποία μπορείτε να εναλλάξετε την επεξεργάσιμη και την ορατή σημαία.Αυτή η εξαίρεση μπορεί τότε να δημιουργηθεί από μεθόδους που δημιουργούνται από _WRAP_METHOD() με επιλογή δημιουργία σφάλματος (errthrow).Αυτό έχει τα ακόλουθα πλεονεκτήματα: <placeholder-1/>Αυτό εμπεριέχει μια ποικιλία εργαλείων, μερικά από τα οποία ξεπερασμένα, αλλά τουλάχιστον δουλεύουν και χρησιμοποιήθηκαν με επιτυχία από αρκετά έργα.Αυτό εμπεριέχει τη χρήση των κλάσεων <classname>Gtk::ActionGroup</classname>, <classname>Gtk::Action</classname> και <classname>UIManager</classname>, που όλες τους πρέπει να δημιουργηθούν μέσα από τις μεθόδους τους <methodname>create()</methodname>, που επιστρέφουν τις <classname>RefPtr</classname>s.Αυτό είναι ένα πλήρως λειτουργικό παράδειγμα που ορίζει και χρησιμοποιεί προσαρμοσμένα σήματα.Αυτό είναι ένα παράδειγμα προγράμματος με δύο νήματα, ένα νήμα GUI, όπως σε όλα τα προγράμματα της <application>gtkmm</application> και ένα με νήμα εργασίας. Το νήμα εργασίας δημιουργείται όταν πατάτε το πλήκτρο <literal>Start work</literal>. Διαγράφεται όταν η εργασία τελειώσει, όταν πατάτε το πλήκτρο <literal>Stop work</literal>, ή όταν πατάτε το πλήκτρο <literal>Quit</literal>.Αυτό παρουσιάζεται στο παράδειγμα αναδυόμενου προσαρμοσμένου μενού.Αυτό παρουσιάζεται στο παράδειγμα drag_and_drop.Αυτό είναι εύκολο να διορθώσετε στη βιβλιοθήκη C, γιαυτό στείλτε μια διόρθωση στον σχετικό συντηρητή.Αυτό είναι όπως το απλό παράδειγμα, αλλά <placeholder-1/>Αυτή είναι μια από τις θέσεις όπου η ομορφιά της C++ πραγματικά εμφανίζεται. Κάποιος δεν θα σκεφτόταν να δημιουργήσει υποκλάση ενός γραφικού συστατικού GTK+ απλά για να αντικαταστήσει τη μέθοδό ενέργειας του· είναι απλά υπερβολικό πρόβλημα. Στην GTK+, χρησιμοποιείτε σχεδόν πάντα σήματα για να κάνετε τα πράγματα, εκτός και γράφετε ένα νέο γραφικό συστατικό. Αλλά λόγω των μεθόδων αντικατάστασης είναι τόσο εύκολο στη C++, είναι πλήρως πρακτικό - και λογικό - να δημιουργήσετε μια υποκλάση ενός πλήκτρου για αυτόν τον σκοπό.Αυτή είναι η δήλωση της μεθόδου <methodname>pack_start()</methodname>:Αυτό δεν είναι καθαρά μια <application>gtkmm</application> ή ένα θέμα γραφικής διεπαφής χρήστη. Η <application>gtkmm</application> χρησιμοποιεί την <application>libsigc++</application> για να υλοποιήσει τους συσκευαστές μεσολαβητή για το σύστημα σήματος <application>GTK+</application>, αλλά για νέα, μη GTK+ σήματα, μπορείτε να δημιουργήσετε καθαρά σήματα C++, χρησιμοποιώντας το πρότυπο <classname>sigc::signal&lt;&gt;</classname>.Αυτή η μακροεντολή μπορεί να χρησιμοποιηθεί για να συσκευάσει δομές που δεν προσαρμόζονται σε οποιαδήποτε ειδική κατηγορία.Αυτή η μακροεντολή δημιουργεί έναν κατασκευαστή με ορίσματα, ισοδύναμο με μια συνάρτηση C <function>*_new()</function>. Στην πραγματικότητα δεν καλεί τη συνάρτηση <function>*_new()</function>, αλλά θα δημιουργήσει απλά έναν ισοδύναμο κατασκευαστή με τους ίδιους τύπους ορίσματος. Παίρνει μια υπογραφή κατασκευαστή C++ και ένα όνομα συνάρτησης C.Αυτή η μακροεντολή δημιουργεί έναν προεπιλεγμένο κατασκευαστή χωρίς ορίσματα.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για μια δομή μη <classname>GObject</classname>, καταχωρισμένη με <function>g_boxed_type_register_static()</function>.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για μια αδιαφανή δομή μετρημένης αναφοράς. Ο συσκευαστής C++ δεν μπορεί να είναι άμεσα αρχικοποιημένος και μπορεί μόνο να χρησιμοποιηθεί με την <classname>Glib::RefPtr</classname>.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για μια απλή μεταβιβάσιμη δομή όπως <classname>GdkRectangle</classname>. Είναι παρόμοια με την <function>_CLASS_BOXEDTYPE</function>, αλλά η δομή C δεν παραχωρείται δυναμικά.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για έναν τύπο που παράγεται από την <classname>GObject</classname>, αλλά του οποίου ο συσκευαστής δεν παράγεται από την <classname>Gtk::Object</classname>.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για έναν τύπο που παράγεται από <classname>GTypeInterface</classname>.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για έναν τύπο του οποίου ο συσκευαστής παράγεται από την <classname>Gtk::Object</classname>, όπως ένα γραφικό συστατικό ή διάλογο.Αυτή η μακροεντολή δηλώνει έναν συσκευαστή για μια αδιαφανή δομή που έχει ελεύθερες συναρτήσεις και συναρτήσεις αντιγραφής. Οι νέες και ελεύθερες συναρτήσεις καθώς και οι συναρτήσεις αντιγραφής θα χρησιμοποιηθούν για αρχικοποίηση του προεπιλεγμένου κατασκευαστή, για αντιγραφή κατασκευαστή και καταστροφέα.Αυτή η μακροεντολή δημιουργεί μια απαρίθμηση C++ για να συσκευάσει μια απαρίθμηση C. Πρέπει να ορίσετε το επιθυμητό όνομα C++ και το όνομα της υποκείμενης απαρίθμησης C.Αυτή η μακροεντολή δημιουργεί μια κλάση εξαίρεσης C++, που παράγεται από Glib::Error, με μια απαρίθμηση κώδικα και μια μέθοδο code(). Πρέπει να ορίσετε το επιθυμητό όνομα C++, το όνομα της αντίστοιχης απαρίθμησης C και το πρόθεμα για τις τιμές απαρίθμησης C.Αυτή η μακροεντολή δημιουργεί έναν κώδικα αρχικοποίησης για τη διεπαφή.Αυτή η μακροεντολή παράγει το σήμα τεχνοτροπίας libsigc++ της C++ για να συσκευάσει ένα σήμα GObject. Στην πραγματικότητα παράγει μια δημόσια μέθοδο στοιχείου πρόσβασης, όπως <function>signal_clicked()</function>, που επιστρέφει ένα αντικείμενο μεσολάβησης. Η <command>gmmproc</command> χρησιμοποιεί το αρχείο .defs για να ανακαλύψει τους τύπους παραμέτρου C και το .m4 μετατρέπει αρχεία για να ανακαλύψει τον κατάλληλο τύπο μετατροπών.Αυτή η μακροεντολή δημιουργεί μια μέθοδο C++ για συσκευασία μιας ιδιότητας GObject C. Πρέπει να ορίσετε το όνομα της ιδιότητας και τον επιθυμητό τύπο C++ για την ιδιότητα. Η <command>gmmproc</command> χρησιμοποιεί το αρχείο .defs για να ανακαλύψει τον τύπο C και να μετατρέψει τα αρχεία .m4 για να βρει κατάλληλες μετατροπές τύπου.Αυτή η μακροεντολή παράγει τη μέθοδο C++ για να συσκευάσει μια συνάρτηση C.Αυτή η μακροεντολή παράγει τη μέθοδο C++ για να συσκευάσει μια εικονική συνάρτηση C.Αυτή η μακροεντολή είναι παρόμοια με την <function>_WRAP_METHOD()</function>, αλλά δημιουργεί μόνο την τεκμηρίωση για τη μέθοδο C++ που συσκευάζει μια συνάρτηση C. Χρησιμοποιήστε το όταν πρέπει να κωδικοποιήσετε με το χέρι τη μέθοδο, αλλά θέλετε να χρησιμοποιήσετε την τεκμηρίωση που πρέπει να δημιουργηθεί αν η μέθοδος είχε δημιουργηθεί.Αυτή η μακροεντολή δημιουργεί μια ομάδα τεκμηρίωσης Doxygen για την απαρίθμηση. Αυτό είναι χρήσιμο για απαριθμήσεις που δεν μπορούν να συσκευαστούν με <function>_WRAP_ENUM()</function> επειδή ορίζονται σύνθετα (ίσως χρησιμοποιώντας μακροεντολές C), αλλά η συμπερίληψη της δημιουργούμενης τεκμηρίωσης απαρίθμησης είναι ακόμα επιθυμητή. Χρησιμοποιείται με την ίδια σύνταξη ως <function>_WRAP_ENUM()</function> και επεξεργάζεται επίσης τις ίδιες επιλογές (αν και ο NO_GTYPE αγνοείται απλά επειδή δεν κάνει καμιά διαφορά όταν δημιουργεί μόνο την τεκμηρίωση απαρίθμησης).Αυτή η μακροεντολή θα χρησιμοποιηθεί όταν αρχικοποιείτε την <literal>gettext</literal> στον πηγαίο κώδικά σας.Αυτό σημαίνει ότι οποιαδήποτε μέθοδος που παίρνει ένα όρισμα <type>const Glib::RefPtr&lt;BaseType&gt;</type> μπορεί επίσης να πάρει έναν <type>const Glib::RefPtr&lt;DerivedType&gt;</type>. Η μετατροπή είναι σιωπηρή, ακριβώς όπως θα ήταν για έναν κανονικό δείκτη.Αυτό το πρόγραμμα περιέχει μια μοναδική κλάση, <classname>MyArea</classname>, που είναι υποκλάση της <classname>Gtk::DrawingArea</classname> και περιέχει μια συνάρτηση μέλους <methodname>on_draw()</methodname>. Αυτή η συνάρτηση καλείται όποτε η εικόνα στην περιοχή σχεδίασης χρειάζεται ανασχεδιασμό. Περνιέται ένας δείκτης <classname>Cairo::RefPtr</classname> στην <classname>Cairo::Context</classname> που χρησιμοποιούμε για τη σχεδίαση. Ο ενεργός κώδικας σχεδίασης ορίζει το χρώμα που θέλουμε να χρησιμοποιήσουμε για σχεδίαση χρησιμοποιώντας την <methodname>set_source_rgb()</methodname> που παίρνει ορίσματα ορίζοντας τα συστατικά κόκκινο, πράσινο και γαλάζιο του επιθυμητού χρώματος (έγκυρες τιμές είναι μεταξύ 0 και 1). Μετά τον ορισμό του χρώματος, δημιουργούμε μια νέα διαδρομή χρησιμοποιώντας τις συναρτήσεις <methodname>move_to()</methodname> και <methodname>line_to()</methodname> και έπειτα βάφουμε αυτήν τη διαδρομή με <methodname>stroke()</methodname>.Αυτό παρέχει μια δομή καταλόγου για τα πηγαία αρχεία .hg και .ccg και τα δημιουργούμενα αρχεία .h και .cc, με τα αρχεία συμπερίληψης Automake <filename>filelist.am</filename> που μπορούν να ορίσουν τα ποικίλα αρχεία σε χρήση, όσον αφορά γενικές μεταβλητές Automake. Η δομή καταλόγου φαίνεται συνήθως ως εξής, αφού έχουμε μετονομάσει τους καταλόγους κατάλληλα: <placeholder-1/>Αυτό απαιτεί έναν αριθμό από κανόνες να παρατηρούνται κατά την εγγραφή πολυνηματικών προγραμμάτων χρησιμοποιώντας την <application>gtkmm</application>. Αυτοί εκτίθενται παρακάτω, αλλά σημειώστε ένα σημείο ότι απαιτείται ιδιαίτερη φροντίδα όταν παράγεται κλάσεις από την <classname>sigc::trackable</classname>, επειδή τα αποτελέσματα δεν είναι διαισθητικά (δείτε ιδιαίτερα τα παρακάτω σημεία 4 και 5).Αυτή η ενότητα περιγράφει κυρίως τι μπορείτε να περιμένετε σε ένα σύστημα Λίνουξ, όταν χρησιμοποιείτε το <ulink url="http://www.gnu.org/software/gdb/">αποσφαλματωτής gdb</ulink>.Αυτή η ενότητα είναι απλά μια συγκέντρωση σοφίας, γενικές οδηγίες τεχνοτροπίας και συμβουλές για δημιουργία εφαρμογών <application>gtkmm</application>.Αυτή η απλή εφαρμογή σχεδιάζει μια καμπύλη με Cairo και εμφανίζει τα σημεία ελέγχου για κάθε άκρο της καμπύλης.Αυτό το απλό παράδειγμα εμφανίζει πώς να φορτώσετε ένα αρχείο <application>Glade</application> στον χρόνο εκτέλεσης και να προσπελάσετε τα γραφικά συστατικά με την <application>Gtk::Builder</application>.Αυτό λέει στο gmmproc ότι η <function>*_new()</function> της C έχει μια τελική παράμετρο GError** που πρέπει να αγνοηθεί.Αυτή η μεταβλητή πρέπει να αναφέρει το σωστό όνομα βιβλιοθήκης και αυτό το όνομα βιβλιοθήκης πρέπει να χρησιμοποιηθεί για να σχηματίσει τα ονόματα μεταβλητών <varname>_SOURCES</varname>, <varname>_LDFLAGS</varname> και <varname>_LIBADD</varname>. Επιτρέπεται η χρήση μεταβλητών που αντικαθίστανται από το <filename>configure</filename> όπως <varname>@SOMETHINGMM_API_VERSION@</varname> ως τμήματος των ονομάτων μεταβλητών.Λήξεις χρόνουΛήξεις χρόνου, είσοδος/έξοδος και αδρανείς συναρτήσειςΗ πρόσβαση ενός γραφικού συστατικού, για παράδειγμα σε ένα διάλογο <methodname>show()</methodname>, χρησιμοποιήστε τη μέθοδο <methodname>get_widget()</methodname>, δίνοντας το όνομα του γραφικού συστατικού. Αυτό το όνομα πρέπει να οριστεί στο παράθυρο ιδιοτήτων της <application>Glade</application>. Αν το γραφικό συστατικό δεν μπόρεσε να βρεθεί, ή είναι σε εσφαλμένο τύπο, τότε ο δείκτης θα οριστεί σε 0. <placeholder-1/>Για να το πετύχετε, θα πρέπει να χρησιμοποιήσετε τις κανονικές μεθόδους <classname>Gtk::TreeView</classname><methodname>insert_column()</methodname> και <methodname>append_column()</methodname>, έπειτα να χρησιμοποιήσετε την <methodname>get_column_cell_renderer()</methodname> για να πάρετε την <classname>Gtk::CellRenderer</classname> που χρησιμοποιείται από αυτήν τη στήλη.Για να προσθέσετε ένα νέο αρχείο στον κατάλογο των πρόσφατων εγγράφων, στην πιο απλή περίπτωση, χρειάζεστε μόνο να δώσετε το URI. Για παράδειγμα:Για την προσθήκη γραφικών συστατικών σε μια περιοχή ενέργειας, χρησιμοποιήστε τη μέθοδο <methodname>add_action_widget()</methodname>. Θα συσκευαστούν δίπλα στα προεπιλεγμένα κουμπιά. Χρησιμοποιήστε τη μέθοδο <methodname>remove_action_widget()</methodname> για αφαίρεση των γραφικών συστατικών.Για να ξεκινήσουμε την εισαγωγή μας στη <application>gtkmm</application>, θα αρχίσουμε με το πιο απλό δυνατό πρόγραμμα. Αυτό το πρόγραμμα θα δημιουργήσει ένα κενό παράθυρο 200 x 200 εικονοστοιχεία.Για να αλλάξετε την επιλογή, ορίστε έναν <classname>Gtk::TreeModel::iterator</classname> ή <classname>Gtk::TreeModel::Row</classname>, ως εξής:Για την αλλαγή της εμφανιζόμενης τιμής, χρησιμοποιήστε τη μέθοδο <methodname>set_fraction()</methodname>, περνώντας έναν <type>αριθμό διπλής ακρίβειας</type> μεταξύ 0.0 και 1.0 για να δώσετε το νέο ποσοστό.Για τον έλεγχο των γραμμών που μπορούν να επιλεγούν, χρησιμοποιήστε τη μέθοδο <methodname>set_select_function()</methodname>, δίνοντας μια επανάκληση <classname>sigc::slot</classname>. Για παράδειγμα:Για να πειστείτε ότι το κάνατε σωστά, ίσως θελήσετε να προσθέσετε μια μετάφραση για νέες τοπικές ρυθμίσεις. Για να το κάνετε αυτό, πηγαίνετε στον υποκατάλογο <filename>po</filename> του έργου σας και εκτελέστε την ακόλουθη εντολή: <placeholder-1/>Για τον ορισμό ενός πλήκτρου επιταχυντή για περιήγηση πληκτρολογίου, τοποθετήστε μια υπογράμμιση πριν από έναν από τους χαρακτήρες της ετικέτας και ορίστε <literal>true</literal> (αληθές) για την προαιρετική παράμετρο <literal>mnemonic</literal> (μνημονική). Για παράδειγμα:Για την αναγνώριση ενός πατήματος του δεξιού πλήκτρου του ποντικιού, χρειάζεστε να χειριστείτε το σήμα <literal>button_press_event</literal> και να ελέγξετε ακριβώς ποιο κουμπί πατήθηκε. Επειδή η <classname>TreeView</classname> χειρίζεται κανονικά αυτό το σήμα πλήρως, χρειάζεστε ή να αντικαταστήσετε τον προεπιλεγμένο χειριστή σήματος σε μια παράγωγη κλάση <classname>TreeView</classname>, ή να χρησιμοποιήσετε την <methodname>connect_notify()</methodname> αντί για την <methodname>connect()</methodname>. Θα θέλετε προφανώς επίσης να καλέσετε τον προεπιλεγμένο χειριστή πριν να κάνετε οτιδήποτε άλλο, έτσι ώστε το δεξιό πάτημα να προκαλέσει να επιλεγεί πρώτα τη γραμμή.Για τον προσδιορισμό της τρέχουσας ορατής σελίδας, χρησιμοποιήστε τη μέθοδο <methodname>get_current_page()</methodname> και περάστε το αποτέλεσμα στη <methodname>get_nth_page()</methodname>, που επιστρέφει έναν δείκτη στο ενεργό γραφικό συστατικό. Για προγραμματιστική αλλαγή της τρέχουσας σελίδας, χρησιμοποιήστε τη μέθοδο <methodname>set_current_page()</methodname>.Για να προσδιορίσετε ποιο πλήκτρο πατήθηκε ή απελευθερώθηκε διαβάζετε την τιμή της <varname>GdkEventKey::keyval</varname> και την συγκρίνετε με μια σταθερά στο αρχείο κεφαλίδας <filename>&lt;gdk/gdkkeysyms.h&gt;</filename>. Οι καταστάσεις των πλήκτρων τροποποίησης (Shift, Ctrl, κλπ.) είναι διαθέσιμες ως σημαίες δυαδικών ψηφίων στη <varname>GdkEventKey::state</varname>.Για να βρείτε την τρέχουσα ορατή σελίδα, χρησιμοποιήστε τη μέθοδο <methodname>get_current_page()</methodname>. Αυτή επιστρέφει τον αριθμό της σελίδας και έπειτα καλώντας την <methodname>get_nth_page()</methodname> με αυτόν τον αριθμό θα σας δώσει έναν δείκτη στο ενεργό θυγατρικό γραφικό συστατικό.Για να βρείτε ποιο στοιχείο, αν υπάρχει, έχει επιλέξει ο χρήστης από το ComboBox, καλέστε <methodname>ComboBox::get_active()</methodname>. Αυτό επιστρέφει μια <classname>TreeModel::iterator</classname>, που μπορείτε να απομακρύνετε την αναφορά σε μια <classname>Row</classname> για να διαβάσετε τις τιμές στις στήλες σας. Για παράδειγμα, μπορείτε να διαβάσετε μια ακέραιη τιμή αναγνωριστικού από το πρότυπο, αν και έχετε επιλέξει να εμφανίζεται μόνο σε ανθρωπίνως αναγνώσιμη περιγραφή στο σύνθετο πλαίσιο. Για παράδειγμα:Για να κάνετε οποιαδήποτε σχεδίαση στο <application>gtkmm</application> με το Cairo, πρέπει πρώτα να δημιουργήσετε ένα αντικείμενο <classname>Cairo::Context</classname>. Αυτή η κλάση κρατά όλες τις παραμέτρους κατάστασης των γραφικών που περιγράφουν πώς πρόκειται να γίνει η σχεδίαση. Αυτό περιλαμβάνει πληροφορίες όπως πλάτος γραμμής, χρώμα, την επιφάνεια για σχεδίαση και πολλά άλλα. Αυτό επιτρέπει στις ενεργές λειτουργίες σχεδίασης να πάρουν λιγότερα ορίσματα για να απλοποιήσουν τη διεπαφή. Στην <application>gtkmm</application>, μια <classname>Cairo::Context</classname> δημιουργείται καλώντας τη συνάρτηση <methodname>Gdk::Window::create_cairo_context()</methodname>. Αφού τα περιεχόμενα Cairo είναι αντικείμενα με μετρημένες αναφορές, αυτή η συνάρτηση επιστρέφει ένα αντικείμενο <classname>Cairo::RefPtr&lt;Cairo::Context&gt;</classname>.Για να το κάνετε αυτό, χρειάζεται να καλέσετε τη μέθοδο <methodname>pulse()</methodname> σε κανονικά διαστήματα. Μπορείτε επίσης να επιλέξετε το μέγεθος βήματος, με τη μέθοδο <methodname>set_pulse_step()</methodname>.Για σχεδίαση μιας έλλειψης, μπορείτε να κλιμακώσετε τον τρέχοντα πίνακα μετασχηματισμού κατά διαφορετικά ποσά στις κατευθύνσεις Χ και Υ. Για παράδειγμα, για τη σχεδίαση μιας έλλειψης με κέντρο στο <varname>x</varname>, <varname>y</varname> και μέγεθος <varname>width</varname>, <varname>height</varname>: <placeholder-1/>Για την ενεργοποίηση αυτής της λειτουργίας, πρέπει να δημιουργήσετε ένα αντικείμενο <classname>EntryCompletion</classname> και να το δώσετε στο γραφικό συστατικό <classname>Entry</classname> μέσα από τη μέθοδο <methodname>set_completion()</methodname>.Για να βρείτε ποιες γραμμές έχει επιλέξει ο χρήστης, πάρτε το αντικείμενο <classname>Gtk::TreeView::Selection</classname> από την <classname>TreeView</classname>, ως εξής:Για την εύρεση των προορισμών που είναι προς το παρόν διαθέσιμοι στην <classname>Clipboard</classname> για επικόλληση, καλέστε τη μέθοδο <methodname>request_targets()</methodname>, ορίζοντας μια μέθοδο για κλήση με την πληροφορία. Για παράδειγμα:Για την εύρεση του τύπου του χειριστή σήματος που μπορείτε να συνδέσετε με ένα σήμα, μπορείτε να το κοιτάξετε στην τεκμηρίωση αναφοράς ή στο αρχείο κεφαλίδας. Ιδού ένα παράδειγμα της δήλωσης σήματος που μπορείτε να δείτε στις κεφαλίδες <application>gtkmm</application>:Για να την εξαναγκάσετε να προσκολληθεί στο πλησιέστερο <literal>step_increment</literal>, χρησιμοποιήστε <methodname>set_snap_to_ticks()</methodname>.Για δημιουργία μιας <classname>Gtk::MenuBar</classname> ή <classname>Gtk::Toolbar</classname> την οποία μπορείτε στην πραγματικότητα να εμφανίσετε, θα πρέπει να χρησιμοποιήσετε τη μέθοδο <methodname>UIManager::get_widget()</methodname> και έπειτα να προσθέσετε το γραφικό συστατικό σε έναν περιέκτη. Για παράδειγμα:Για δημιουργία μόνο ενός παραθύρου, ή απλά μόνο ενός από τα θυγατρικά γραφικά συστατικά, μπορείτε να ορίσετε το όνομα ενός θυγατρικού γραφικού συστατικού ως τη δεύτερη παράμετρο. Για παράδειγμα, <placeholder-1/>Για την αναζήτηση πρόσφατα χρησιμοποιημένων αρχείων, η <classname>RecentManager</classname> δίνει αρκετές συναρτήσεις. Για αναζήτηση ενός συγκεκριμένου στοιχείου με το URI του, μπορείτε να χρησιμοποιήσετε τη συνάρτηση <methodname>lookup_item()</methodname>, που θα επιστρέψει μια κλάση <classname>RecentInfo</classname>. Αν το συγκεκριμένο URI δεν υπήρχε στον κατάλογο των πρόσφατων αρχείων, η <methodname>lookup_item()</methodname> εκπέμπει μια εξαίρεση της <classname>RecentManagerError</classname>. Για παράδειγμα:Για να κάνετε την <classname>SpinButton</classname> να 'αναδιπλωθεί' μεταξύ του ανώτερου και κατώτερου ορίου, χρησιμοποιήστε τη μέθοδο <methodname>set_wrap()</methodname>.Για να πάρετε ένα στιγμιότυπο της <application>gtkmm</application> από ένα στιγμιότυπο GObject της C, χρησιμοποιήστε τη συνάρτηση Glib::wrap(). Για παράδειγμαΓια να συσκευάσετε γραφικά συστατικά σε έναν προσαρμοσμένο διάλογο, θα πρέπει να τις συσκευάσετε στην <classname>Gtk::Box</classname>, διαθέσιμη μέσα από <methodname>get_content_area()</methodname>. Για να προσθέσετε απλά μια <classname>Button</classname> στο τέλος του <classname>Dialog</classname>, μπορείτε να χρησιμοποιήσετε τη μέθοδο <methodname>add_button()</methodname>.Για να αποτραπεί η πληκτρολόγηση από τον χρήστη μη αριθμητικών χαρακτήρων στο πλαίσιο καταχώρισης, περάστε <literal>αληθές</literal> στη μέθοδο <methodname>set_numeric()</methodname>.Για προγραμματιστική αλλαγή της επιλεγμένης σελίδας, χρησιμοποιήστε τη μέθοδο <methodname>set_current_page()</methodname>.Για να δεχτείτε τα συμβάντα του πληκτρολογίου, πρέπει πρώτα να; καλέσετε τη συνάρτηση <methodname>Gtk::Widget::add_events()</methodname> με λίγη μάσκα των συμβάντων που ενδιαφέρεστε. Το συμβάν χειριστή σήματος θα δεχτεί ένα όρισμα που εξαρτάται από τον τύπο του συμβάντος. Για συμβάντα πληκτρολογίου είναι ένας <type>GdkEventKey*</type>. Όπως περιγράφτηκε στο <link linkend="sec-xeventsignals">παράρτημα</link>, ο χειριστής σήματος συμβάντος επιστρέφει μια τιμή <type>Μπουλ</type>, για να δείξει ότι το σήμα επεξεργάστηκε πλήρως (<literal>true</literal>) ή να επιτρέψει τη διάδοση του συμβάντος (<literal>false</literal>).Για την απόδοση περισσότερων από μια στήλης προτύπου σε μια στήλη προβολής, χρειάζεται να δημιουργήσετε το γραφικό συστατικό <classname>TreeView::Column</classname> χειροκίνητα και να χρησιμοποιήσετε την <methodname>pack_start()</methodname> για να προσθέσετε τις στήλες του προτύπου σε αυτή.Για απάντηση στο πάτημα του χρήστη σε μια γραμμή ή περιοχή γραμμών, συνδεθείτε με το σήμα ως εξής:Για ανάκτηση της κατάστασης της <classname>ToggleButton</classname>, μπορείτε να χρησιμοποιήσετε τη μέθοδο <methodname>get_active()</methodname>. Αυτή επιστρέφει <literal>true</literal> (αληθές), αν το κουπί είναι "κάτω". Μπορείτε επίσης να ορίσετε την κατάσταση του κουμπιού εναλλαγής, με <methodname>set_active()</methodname>. Σημειώστε ότι, αν το κάνετε αυτό και η κατάσταση στην πραγματικότητα αλλάξει, προκαλεί την εκπομπή του σήματος "πατημένο". Αυτό είναι συνήθως αυτό που θέλετε.Για να δείτε πού συμβαίνει η εξαίρεση, μπορείτε να χρησιμοποιήσετε την εντολή της <application>gdb</application> <userinput>catch throw</userinput>. <placeholder-1/>Για τον ορισμό του τίτλου μιας σελίδας, χρησιμοποιήστε τη μέθοδο <methodname>set_page_title()</methodname>. Η κεφαλίδα και οι πλευρικές εικόνες μιας σελίδας μπορούν να οριστούν με τις μεθόδους <methodname>set_page_header_image()</methodname> και <methodname>set_page_side_image()</methodname>.Για να εγκαταστήσετε την <application>jhbuild</application>, ακολουθήστε τις βασικές οδηγίες εγκατάστασης από το <ulink url="http://developer.gnome.org/jhbuild/unstable/">εγχειρίδιο jhbuild</ulink>. Αφού έχετε εγκαταστήσει την <application>jhbuild</application>, θα πρέπει να αντιγράψετε το αρχείο ρυθμίσεων του δείγματος της <application>jhbuild</application> στον προσωπικό σας κατάλογο εκτελώντας την ακόλουθη εντολή από τον κατάλογο της <application>jhbuild</application>: <screen>$ cp examples/sample.jhbuildrc ~/.jhbuildrc</screen>Για εμφάνιση του αναδυόμενου μενού, χρησιμοποιήστε τη μέθοδο <classname>Gtk::Menu</classname>'s <methodname>popup()</methodname>, που παρέχει το αναγνωριστικό κουμπιού και τον χρόνο ενεργοποίησης, όπως παρέχεται από το σήμα <literal>button_press_event</literal>, που θα χρειαστείτε να χειριστείτε οπωσδήποτε. Για παράδειγμα:Για απλοποίηση της μεταγλώττισης, χρησιμοποιούμε <literal>pkg-config</literal>, που είναι παρόν σε όλες τις (σωστά εγκατεστημένες εγκαταστάσεις) της <application>gtkmm</application>. Αυτό το πρόγραμμα 'ξέρει' τι διακόπτες μεταγλωττιστή απαιτούνται για μεταγλώττιση προγραμμάτων που χρησιμοποιούν τη <application>gtkmm</application>. Η επιλογή <literal>--cflags</literal> προκαλεί τη <literal>pkg-config</literal> να δώσει μια λίστα των περιλαμβανόμενων καταλόγων για να ψάξει ο μεταγλωττιστής· η επιλογή <literal>--libs</literal> ζητά τη λίστα των βιβλιοθηκών ώστε ο μεταγλωττιστής να συνδεθεί και οι κατάλογοι να τους βρουν. Δοκιμάστε να το εκτελέσετε από την προτροπή φλοιού για να δείτε τα αποτελέσματα στο σύστημά σας.Για να ορίσετε ότι κάποιο κείμενο στην ενδιάμεση μνήμη πρέπει να έχει ειδική μορφοποίηση, πρέπει να ορίσετε μια ετικέτα που θα κρατήσει αυτήν την πληροφορία μορφοποίησης και έπειτα θα εφαρμόσει αυτήν την ετικέτα στην περιοχή του κειμένου. Για παράδειγμα, για τον ορισμό της ετικέτας και των ιδιοτήτων της:Για να χρησιμοποιήσετε ένα στιγμιότυπο της <application>gtkmm</application> με μια συνάρτηση C που απαιτεί ένα στιγμιότυπο GObject της C, χρησιμοποιήστε τη συνάρτηση <function>gobj()</function> για να πάρετε έναν δείκτη στο υποκείμενο στιγμιότυπο GObject. Για παράδειγμαΓια την παράκαμψη του, μπορείτε να γράψετε ένα σχόλιο στον πηγαίο κώδικα ακριβώς πριν τη συμβολοσειρά, λέγοντας στους μεταφραστές να χρησιμοποιήσουν τον ειδικό χαρακτήρα, αν είναι διαθέσιμος στις γλώσσες τους. Για τα αγγλικά, μπορείτε τότε να κάνετε μια μετάφραση σε αγγλικά Αμερικής <filename>en_US.po</filename> που χρησιμοποιεί αυτόν τον ειδικό χαρακτήρα.Κουμπιά εναλλαγήςΚουμπί εναλλαγήςΑναφορά στοιχείου εργαλείουΑναφορά ομάδας στοιχείου παλέταςΠαλέτα εργαλείουΠαράδειγμα παλέτας εργαλείουΑναφορά παλέτας εργαλείουΣυμβουλή οθόνηςΑναφορά συμβουλής οθόνηςΣυμβουλές οθόνηςΟι συμβουλές οθόνης είναι τα μικρά παράθυρα πληροφοριών που αναδύονται όταν αφήνετε τον δείκτη σας πάνω από ένα γραφικό συστατικό για λίγα δευτερόλεπτα. Χρησιμοποιήστε την <methodname>set_tooltip_text()</methodname> για να ορίσετε μια συμβολοσειρά κειμένου ως συμβουλή οθόνης σε οποιοδήποτε <classname>Widget</classname>. Οι <classname>Gtk::ToolItem</classname>s δεν είναι <classname>Widget</classname>s, αλλά έχουν την ίδια μέθοδο για διευκόλυνση. Η <classname>Gtk::Tooltip</classname> χρησιμοποιείται για πιο προχωρημένη χρήση συμβουλών οθόνης, όπως εμφάνιση μιας εικόνας καθώς και κειμένου.TreeModel::iterator iter = refTreeSelection-&gt;get_selected();
if(iter) //Αν κάτι έχει επιλεγεί
{
  TreeModel::Row row = *iter;
  //Do something with the row.
}Αναφορά ταξινόμησης τύπου δένδρου (TreeModelSort)Αναφορά TreeSortableΑποθήκευση δένδρουΑποθήκευση δένδρου, για μια ιεραρχίαΠροβολή δένδρου - Μεταφορά και απόθεσηΠροβολή δένδρου (TreeView) - Επεξεργάσιμα κελιάΠροβολή δένδρου - Αποθήκευση λίστας (TreeView - ListStore)Προβολή δένδρου - Αναδυόμενο μενού περιεχομένωνΠροβολή δένδρου - Αποθήκευση λίστας (TreeView - ListStore)Η Qt του Trolltech είναι ο πλησιέστερος ανταγωνιστής με τη <application>gtkmm</application>, έτσι αξίζει συζήτηση.Δοκιμάστε την εκτέλεση του παραδείγματος και αυξήστε το φορτίο του συστήματος. Η ανώτερη γραμμή προόδου θα αυξάνεται σταθερά· η κατώτερη γραμμή θα επιβραδύνεται.Δοκιμάστε να μεταγλωττίσετε και να το εκτελέσετε πριν να συνεχίσουμε. Θα πρέπει να δείτε κάτι σαν αυτό:Δύο πρόσθετες παράμετροι είναι προαιρετικές, για την περίπτωση που η διεπαφή προέρχεται από μια άλλη διεπαφή, που πρέπει να είναι η περίπτωση όταν η GInterface έχει μια άλλη GInterface ως προαπαιτούμενη. Για παράδειγμα, από <filename>loadableicon.hg</filename>: <placeholder-1/>Τυπικά η βιβλιοθήκη συσκευαστή μας πρέπει να ονομαστεί libsomethingmm. Μπορούμε να ξεκινήσουμε αντιγράφοντας το <ulink url="http://git.gnome.org/cgit/mm-common/tree/skeletonmm">πηγαίο δένδρο σκελετού</ulink> από την ενότητα mm-common. <placeholder-1/>Οι αλλαγές διεπαφής χρήστη μπορούν να φανούν πιο γρήγορα, έτσι οι διεπαφές χρήστη μπορούν να βελτιωθούν.UIManagerΑδύνατη η προδήλωση δομώνΔυστυχώς, η ενσωμάτωση με τις τυπικές ροές εισόδου/εξόδου δεν είναι πλήρως αλάνθαστη. Η <application>gtkmm</application> μετατρέπει τις <classname>Glib::ustring</classname>s σε μια ειδική κωδικοποίηση τοπικών ρυθμίσεων (που συνήθως δεν είναι UTF-8), αν τις εξάγεται σε μια <classname>ostream</classname> με <function>operator&lt;&lt;</function>. Παρόμοια, η ανάκτηση της <classname>Glib::ustrings</classname> από την <classname>istream</classname> με <function>operator&gt;&gt;</function> προκαλεί μια μετατροπή στην αντίθετη κατεύθυνση. Αλλά αυτό το σχήμα σπάει, αν περιηγηθείτε μια <classname>std::string</classname>, π.χ. εισάγοντας κείμενο από μια ροή σε μια <classname>std::string</classname> και μετατρέποντας την έπειτα έμμεσα σε μια <classname>Glib::ustring</classname>. Αν η συμβολοσειρά περιείχε χαρακτήρες μη ASCII και οι τρέχουσες τοπικές ρυθμίσεις δεν είναι κωδικοποιημένες ως UTF-8, το αποτέλεσμα είναι μια αλλοιωμένη <classname>Glib::ustring</classname>. Μπορείτε να δουλέψετε γύρω από αυτό με μια χειροκίνητη μετατροπή. Για παράδειγμα, για να ανακτήσετε την <classname>std::string</classname> από μια <classname>ostringstream</classname>: <placeholder-1/>Γιούνιξ και ΛίνουξΕκτός και ο περιέκτης σας είναι ένα παράθυρο ανωτάτου επιπέδου που παράγεται από την <classname>Gtk::Window</classname>, θα πρέπει προφανώς να καλέσετε επίσης την <methodname>Gtk::Widget::set_has_window(false)</methodname> στον κατασκευαστή σας. Αυτό σημαίνει ότι ο περιέκτης σας δεν δημιουργεί την δικιά του <classname>Gdk::Window</classname>, αλλά χρησιμοποιεί το γονικό του παράθυρο. (Σημειώστε τη διαφορά μεταξύ <classname>Gtk::Window</classname> και <classname>Gdk::Window</classname>.) Αν ο περιέκτης σας δεν χρειάζεται τη δικιά του <classname>Gdk::Window</classname> και δεν παράγεται από την <classname>Gtk::Window</classname>, θα πρέπει επίσης να αντικαταστήσετε τη μέθοδο <methodname>on_realize()</methodname> όπως περιγράφηκε στην ενότητα <link linkend="sec-custom-widgets">προσαρμοσμένα γραφικά συστατικά</link>. Και εκτός και ο περιέκτης σας σχεδιάζει άμεσα στο υποκείμενο <classname>Gdk::Window</classname>, θα πρέπει προφανώς να καλέσετε την <methodname>set_redraw_on_allocate(false)</methodname> για να βελτιώσετε την απόδοση.Αντίθετα με τη λύση Unicode UCS-2 των Windows, αυτό δεν απαιτεί καμιά ειδική επιλογή μεταγλωττιστή για επεξεργασία κυριολεκτικών συμβολοσειρών και δεν καταλήγει σε εκτελέσιμα Unicode και βιβλιοθήκες που είναι ασύμβατες με τις αντίστοιχες ASCII.Αντίθετα με τα άλλα γραφικά συστατικά σε αυτήν την ενότητα, τα γραφικά συστατικά φατνωμάτων (pane) δεν περιέχουν ένα αλλά δύο θυγατρικά γραφικά συστατικά, ένα σε κάθε φάτνωμα. Συνεπώς, θα πρέπει να χρησιμοποιήσετε <methodname>add1()</methodname> και <methodname>add2()</methodname> αντί για τη μέθοδο <methodname>add()</methodname>.Σπάνιες λέξειςΠολιτικές αναβάθμισηςΕνημερώστε το <literal>DISTCLEANFILES</literal>: <placeholder-1/>Χρησιμοποιήστε την <classname>Glib::Dispatcher</classname> για να καλέσετε συναρτήσεις <application>gtkmm</application> από νήματα εργασίας (αυτό αναφέρεται με περισσότερη λεπτομέρεια στην επόμενη ενότητα).Χρησιμοποιήστε <methodname>Gtk::Builder::get_widget_derived()</methodname> ως εξής: <placeholder-1/>Χρήση των GNU <application>autoconf</application> και <application>automake</application>! Είναι οι φίλοι σας :). Η <application>Automake</application> εξετάζει τα αρχεία C, καθορίζει πώς εξαρτώνται μεταξύ τους και δημιουργεί ένα <filename>Makefile</filename>, έτσι ώστε τα αρχεία μπορούν να μεταγλωττιστούν με τη σωστή σειρά. Η <application>Autoconf</application> επιτρέπει αυτόματη διαμόρφωση εγκατάστασης λογισμικού, χειρισμό μεγάλου αριθμού ιδιομορφιών του συστήματος για αύξηση της φορητότητας.Χρησιμοποιήστε τις μεθόδους <methodname>append_page()</methodname>, <methodname>prepend_page()</methodname> και <methodname>insert_page()</methodname> για την προσθήκη σελίδων με καρτέλες στο <literal>Notebook</literal> (σημειωματάριο), παρέχοντας στο θυγατρικό γραφικό συστατικό και το όνομα για την καρτέλα.Χρησιμοποιήστε τις μεθόδους <methodname>append_page()</methodname>, <methodname>prepend_page</methodname> και <methodname>insert_page()</methodname> για την προσθήκη σελίδων στη <classname>Assistant</classname>, παρέχοντας το θυγατρικό γραφικό συστατικό για κάθε σελίδα.Χρησιμοποιήστε την τελευταία παράμετρο GError** της συνάρτησης C για να δημιουργήσετε μια εξαίρεση.Χρησιμοποιήστε την τελευταία παράμετρο GError** της εικονικής συνάρτησης C (αν υπάρχει μία) για τη δημιουργία εξαίρεσης.Χρησιμοποιήστε αυτές τις μακροεντολές αν συσκευάζετε μια απλή δομή ή τύπου πλαισίου που παρέχει άμεση πρόσβαση στα μέλη δεδομένων, για να δημιουργήσετε λήπτες και μεταλλάκτες (getters and setters) για τα μέλη δεδομένων.Χρησιμοποιήστε αυτές τις μακροεντολές για αυτόματη παροχή ληπτών και μεταλλακτών (getters and setters) για ένα μέλος δεδομένων που είναι τύπου δείκτη. Για τη συνάρτηση δεκτών, θα δημιουργήσει δύο μεθόδους, μια σταθερή και μια μη σταθερή.χρησιμοποιήστε αυτές τις μακροεντολές για να δώσετε λήπτες και μεταλλάκτες (getters and setters) για ένα μέλος δεδομένων που είναι τύπου <classname>GObject</classname> που πρέπει να αναφερθεί πριν επιστραφεί.Χρησιμοποιείται σε συνδυασμό με την επιλογή <literal>slot_name</literal> για να ορίσει το όνομα της συνάρτησης επανάκλησης επικόλλησης που χειρίζεται την εξαγωγή της υποδοχής και την κλήση της έπειτα. Η διεύθυνση αυτής της επανάκλησης περνιέται επίσης στη συνάρτηση C που η μέθοδος συσκευάζει.Χρήσιμες μέθοδοιΧρήση προσαρμογών με τον εύκολο τρόποΧρήση Glib::DispatcherΧρησιμοποιώντας ένα γραφικό συστατικό <application>gtkmm</application>Χρήση ενός προτύπουΧρησιμοποιώντας παράγωγα γραφικά συστατικάΧρήση χαρακτήρων μη ASCII στις συμβολοσειρέςΧρήση της έκδοσης git της <application>gtkmm</application>VineΘεωρούμε επίσης ότι χρησιμοποιείτε autotools (π.χ. <application>automake</application> και <application>autoconf</application>) για τη δόμηση του έργου σας και ότι χρησιμοποιείτε <ulink url="http://git.gnome.org/browse/gnome-common/tree/autogen.sh"><literal>./autogen.sh</literal> από την <application>gnome-common</application></ulink>, που, μεταξύ άλλων, φροντίζει κάποια αρχικοποίηση της <application>intltool</application>.Θα συζητήσουμε επίσης το γραφικό συστατικό <classname>Gtk::Paned</classname>, που επιτρέπει τη διαίρεση ενός παραθύρου σε δύο ξεχωριστά "φατνώματα". Αυτό το γραφικό συστατικό στην πραγματικότητα περιέχει δύο θυγατρικά γραφικά συστατικά, αλλά ο αριθμός ορίστηκε έτσι ώστε να φαίνεται κατάλληλος.Μόλις σας είπαμε ότι το σήμα <literal>clicked</literal> του πλήκτρου αναμένει να καλέσει μια μέθοδο χωρίς ορίσματα. Όλα τα σήματα έχουν απαιτήσεις όπως αυτό - δεν μπορείτε να αγκιστρώσετε μια συνάρτηση με δύο ορίσματα σε ένα σήμα που δεν περιμένει κανένα (εκτός και χρησιμοποιείτε έναν προσαρμογέα, όπως <function>sigc::bind()</function>, φυσικά). Συνεπώς, είναι σημαντικό να ξέρετε ποιος τύπος χειριστή σήματος θα αναμένεται για να συνδεθεί με το δοσμένο σήμα.Κάναμε μια νέα ομάδα δηλώνοντας απλά μια μεταβλητή, <literal>group</literal>, του τύπου <classname>Gtk::RadioButton::Group</classname>. Έπειτα κάναμε τρία ραδιοπλήκτρα, χρησιμοποιώντας έναν κατασκευαστή για να κάνουμε καθένα τους μέρος της <literal>group</literal>.Κάνουμε μια κλήση στη <methodname>Cairo::Context::scale()</methodname>, περνώντας το πλάτος και το ύψος της περιοχής σχεδίασης. Αυτό κλιμακώνει το σύστημα συντεταγμένων χώρου χρήστη, έτσι ώστε το πλάτος και το ύψος του γραφικού συστατικού να είναι ίσα με 1.0 'μονάδες'. Δεν υπάρχει ειδικός λόγος να κλιμακώσουμε το σύστημα συντεταγμένων σε αυτήν την περίπτωση, αλλά μερικές φορές μπορεί να κάνουμε τη σχεδίαση λειτουργιών ευκολότερα.Πρέπει να αναφέρουμε όλα τα αρχεία μας <filename>.hg</filename> και <filename>.ccg</filename> στο αρχείο <filename>skeleton/src/filelist.am</filename>, τυπικά στη μεταβλητή <varname>files_hg</varname>.Τώρα χρησιμοποιούμε std::vector σε αρκετές μεθόδους αντί για τους ενδιάμεσους τύπους *Handle για να κάνουμε την API πιο σαφή.Πρέπει τώρα να δημιουργήσουμε τα πρώτα μας αρχεία <filename>.hg</filename> και <filename>.ccg</filename>, για να συσκευάσουμε ένα από τα αντικείμενα στη βιβλιοθήκη C. Ένα ζεύγος παραδείγματος πηγαίων αρχείων που ήδη υπάρχει: <filename>skeleton.ccg</filename> και <filename>skeleton.hg</filename>. Δημιουργήστε αντίγραφα αυτών των αρχείων όπως χρειάζεται.Έπειτα συνδέουμε έναν χειριστή σήματος στο <literal>m_button</literal> το σήμα του <literal>clicked</literal> (πατημένο). Αυτό εκτυπώνει τον φιλικό μας χαιρετισμό στην <literal>stdout</literal> (τυπική έξοδος).Είπαμε στη <application>gtkmm</application> να βάλει και τα τρία <classname>RadioButton</classname> στην ίδια ομάδα παίρνοντας την ομάδα με <methodname>get_group()</methodname> και χρησιμοποιώντας <methodname>set_group()</methodname> για να πούμε στις άλλες <classname>RadioButton</classname> να μοιραστούν αυτήν την ομάδα.Θα εξηγήσουμε τώρα κάθε γραμμή του παραδείγματοςΘα θέλαμε πάρα πολύ να ακούσουμε οποιαδήποτε προβλήματα έχετε μαθαίνοντας το <application>gtkmm</application> με αυτό το έγγραφο και θα εκτιμούσαμε εισαγωγή σχετικά με βελτιώσεις. Παρακαλούμε, δείτε την ενότητα <link linkend="chapter-contributing">Συνεισφορά</link> για παραπέρα πληροφορίες.Το συνδέουμε στο αντικείμενο <classname>Gtk::Button</classname> που λέγεται <varname>button</varname>.Έχουμε τώρα μάθει αρκετά για να κοιτάξουμε ένα πραγματικό παράδειγμα. Σύμφωνα με μια παλιά παράδοση της επιστήμης των υπολογιστών, θα εισάγουμε τώρα Hello World, στη <application>gtkmm</application>:Τι συμβαίνει αν ένα γραφικό συστατικό αναδιαμορφώνει τα πεδία <parameter>upper</parameter> ή <parameter>lower</parameter> της <classname>Adjustment</classname> του, όπως όταν ένας χρήστης προσθέτει περισσότερο κείμενο στο γραφικό συστατικό κειμένου; Σε αυτήν την περίπτωση εκπέμπει το σήμα <literal>changed</literal>.Ποια είναι η διαφορά μεταξύ διακένου (που ορίστηκε όταν δημιουργείται το πλαίσιο (box)) και συμπλήρωσης (που ορίζεται όταν συσκευάζονται στοιχεία); Το διάκενο προστίθεται μεταξύ αντικειμένων και η συμπλήρωση προστίθεται σε όποια πλευρά του γραφικού συστατικού. Η παρακάτω εικόνα πρέπει να το ξεκαθαρίζει:Όταν η <varname>pixbuf</varname> βγαίνει εκτός εμβέλειας μιας <methodname>unref()</methodname> θα συμβεί στο παρασκήνιο και δεν χρειάζεται να ανησυχείτε για αυτό πια. Δεν υπάρχει κανένα <literal>new</literal>, έτσι δεν υπάρχει κανένα <literal>delete</literal>.Όταν ένας κατασκευαστής πρέπει να είναι μερικώς χειρόγραφος επειδή, για παράδειγμα, οι παράμετροι της συνάρτησης C <function>*_new()</function> δεν αντιστοιχούν άμεσα στις ιδιότητες αντικειμένου, ή επειδή η συνάρτηση <function>*_new()</function> κάνει περισσότερα από το να καλεί την <function>g_object_new()</function>, η μακροεντολή <function>_CONSTRUCT()</function> μπορεί να χρησιμοποιηθεί στο αρχείο .ccg για την αποθήκευση κάποιας εργασίας. Η μακροεντολή <function>_CONSTRUCT</function> παίρνει μια σειρά ονομάτων και τιμών ιδιότητας. Για παράδειγμα, από <filename>button.ccg</filename>: <placeholder-1/>Όταν ένας προορισμός απόθεσης έχει αποδεχτεί ένα μεταφερόμενο στοιχείο, συγκεκριμένα σήματα θα εκπεμφθούν, ανάλογα με το ποια ενέργεια έχει επιλεγεί. Για παράδειγμα, ο χρήστης μπορεί να έχει πατημένο το πλήκτρο <keycap>Shift</keycap> για να ορίσει μια <literal>move</literal> αντί για μια <literal>copy</literal>. Να θυμάστε ότι ο χρήστης μπορεί να επιλέξει μόνο τις ενέργειες που έχετε ορίσει στις κλήσεις σας στις <methodname>drag_dest_set()</methodname> και <methodname>drag_source_set()</methodname>.Όταν ένα πρόγραμμα ματαιώνεται λόγω μιας ανεπίλυτης εξαίρεσης C++, είναι μερικές φορές δυνατή η χρήση ενός αποσφαλματωτή για την εύρεση της θέσης όπου συνέβη η εξαίρεση. Αυτό είναι πιο δύσκολο από ό,τι συνήθως, αν η εξαίρεση συνέβη από έναν χειριστή σήματος.Κατά την παραγωγή από <classname>Gtk::Container</classname>, θα πρέπει να αντικαταστήσετε τις παρακάτω εικονικές μεθόδους: <placeholder-1/>Όταν προέρχεται από την <classname>Gtk::Widget</classname>, θα πρέπει να αντικαταστήσετε τις παρακάτω εικονικές μεθόδους. Οι σημειωμένες μέθοδοι (προαιρετικά) χρειάζεται να μην αντικατασταθούν σε όλα τα προσαρμοσμένα γραφικά συστατικά. Οι μέθοδοι βασικής κλάσης μπορεί να είναι κατάλληλες. <placeholder-1/>Όταν το πλήκτρο εκπέμπει το σήμα του <literal>clicked</literal>, θα κληθεί η <methodname>on_button_clicked()</methodname> will be called.Όταν η εφαρμογή εκτελείται, η βιβλιοθήκη <application>gettext</application> ελέγχει τον κατάλογο όλου του συστήματος για να δει αν υπάρχει ένα αρχείο <filename>.mo</filename> για το περιβάλλον τοπικών ρυθμίσεων του χρήστη (μπορείτε να ορίσετε τις τοπικές ρυθμίσεις με, για παράδειγμα, "export LANG=de_DE.UTF-8" από μια κονσόλα bash). Αργότερα, όταν το πρόγραμμα φτάσει μια κλήση <literal>gettext</literal>, αναζητά μια μετάφραση της συγκεκριμένης συμβολοσειράς. Αν δεν βρεθεί καμιά, χρησιμοποιείται η αρχική συμβολοσειρά.Όταν το ποντίκι είναι πάνω από το πλήκτρο και ένα πλήκτρο του ποντικιού πατιέται, Θα κληθεί η <methodname>on_button_press()</methodname>.Όταν ο χρήστης ζητά να αντιγράψει κάποια δεδομένα, θα πρέπει να πείτε στο <classname>Clipboard</classname> ποιοι προορισμοί είναι διαθέσιμοι και να δώσετε τις μεθόδους επανάκλησης που μπορεί να χρησιμοποιηθούν για τη λήψη δεδομένων. Σε αυτό το σημείο θα πρέπει να αποθηκεύσετε ένα αντίγραφο των δεδομένων, για να δοθεί όταν το πρόχειρο καλέσει τη μέθοδο επανάκλησης σε απάντηση για μια επικόλληση.Όταν ο χρήστης ζητά την επικόλληση δεδομένων από την <classname>Clipboard</classname>, θα πρέπει να ζητήσετε μια ειδική μορφή και να δώσετε μια μέθοδο επανάκλησης που θα κληθεί με τα ενεργά δεδομένα. Για παράδειγμα:Όταν ο χρήστης εισάγει τυχαίο κείμενο, μπορεί να μην είναι αρκετό να συνδεθεί με το σήμα <literal>changed</literal>, που εκπέμπεται για κάθε πληκτρολογημένο χαρακτήρα. Δεν εκπέμπεται όταν ο χρήστης πατά το πλήκτρο εισαγωγής. Πατώντας το πλήκτρο εισαγωγής ή μετακινώντας την εστίαση του πληκτρολογίου σε άλλο γραφικό συστατικό μπορεί να σημαίνει ότι ο χρήστης έχει τελειώσει την εισαγωγή κειμένου. Για να ειδοποιηθεί για αυτά τα συμβάντα, συνδεθείτε στα σήματα στη <classname>Entry</classname> των <literal>activate</literal> και <literal>focus_out_event</literal>, ως εξής <placeholder-1/>. Τα σήματα <literal>changed</literal> των <classname>ComboBox</classname> και <classname>Entry</classname> εκπέμπονται και τα δύο για κάθε αλλαγή. Δεν πειράζει με ποιο συνδέεστε. Αλλά μόνο το σήμα στη <classname>Entry</classname> του <literal>focus_out_event</literal> είναι χρήσιμο εδώ.Κατά τη χρήση της <function>_CLASS_GOBJECT()</function>, οι κατασκευαστές πρέπει να προστατευτούν (αντί να είναι δημόσιες) και κάθε κατασκευαστής πρέπει να έχει μια αντίστοιχη <function>_WRAP_CREATE()</function> στην δημόσια ενότητα. Αυτό αποτρέπει την κλάση από αρχικοποίηση χωρίς τη χρήση μιας <classname>RefPtr</classname>. Για παράδειγμα: <placeholder-1/>Όταν χρησιμοποιείτε μια <classname>Gtk::TreeStore</classname>, οι γραμμές μπορούν να έχουν θυγατρικές γραμμές, που μπορούν να έχουν τα δικά τους θυγατρικά με τη σειρά τους. Χρησιμοποιήστε <methodname>Gtk::TreeModel::Row::children()</methodname> για τη λήψη του περιέκτη των θυγατρικών <classname>Row</classname>s: <placeholder-1/>Όταν χρησιμοποιείτε αυτήν απλή αντικατάσταση <methodname>append_column()</methodname>, η <classname>TreeView</classname> θα εμφανίσει τα δεδομένα του προτύπου με μια κατάλληλη <classname>CellRenderer</classname>. Για παράδειγμα, οι συμβολοσειρές και οι αριθμοί εμφανίζονται σε ένα απλό γραφικό συστατικό <classname>Gtk::Entry</classname> και οι τιμές Μπουλ εμφανίζονται σε μια <classname>Gtk::CheckButton</classname>. Αυτό είναι συνήθως αυτό που χρειάζεστε. Για άλλους τύπους στηλών, πρέπει ή να συνδεθείτε με μια επανάκληση που μετατρέπει τον τύπο σας σε μια συμβολοσειρά παρουσίασης, με <methodname>TreeViewColumn::set_cell_data_func()</methodname>, ή να παράξει μια προσαρμοσμένη <classname>CellRenderer</classname>. Σημειώστε ότι (χωρίς πρόσημο) μικρός αριθμός δεν υποστηρίζεται από προεπιλογή - Μπορείτε να χρησιμοποιήσετε (χωρίς πρόσημο) ακέραιο ή (χωρίς πρόσημο) μεγάλο αριθμό ως τύπο στήλης στη θέση του.Όταν μεταφορτώσατε την <application>jhbuild</application> από το αποθετήριο git, παίρνετε έναν αριθμό αρχείων των <filename>.modules</filename>, ορίζοντας τις εξαρτήσεις μεταξύ ενοτήτων. Από προεπιλογή η <application>jhbuild</application> δεν χρησιμοποιεί τις μεταφορτωμένες εκδόσεις αυτών των αρχείων, αλλά διαβάζει τις τελευταίες εκδόσεις στο αποθετήριο git. Αυτό συνήθως θέλετε. Αν δεν το θέλετε, χρησιμοποιήστε τη μεταβλητή <varname>use_local_modulesets</varname> στο <filename>.jhbuildrc</filename>.Όταν διαλέγετε μια επιλογή από το πτυσσόμενο μενού, η τιμή από αυτήν τη στήλη θα τοποθετηθεί στην <classname>Entry</classname>.Όταν γράφετε στην καταχώριση, ένα συμβάν απελευθέρωσης πλήκτρου θα εκπεμφθεί, που θα πάει πρώτα στο παράθυρο ανωτάτου επιπέδου (<classname>Gtk::Window</classname>), αφού έχουμε έναν ορισμένο χειριστή συμβάντος να κληθεί πριν, αυτό λέγεται πρώτο (<methodname>windowKeyReleaseBefore()</methodname>). Έπειτα ο προεπιλεγμένος χειριστής καλείται (τον οποίο έχουμε αντικαταστήσει) και μετά από αυτό το συμβάν στέλνεται στο γραφικό συστατικό που έχει την εστίαση, η <classname>Entry</classname> στο παράδειγμά μας και ανάλογα με το αν το επιτρέψουμε, μπορεί να φτάσει στους χειριστές συμβάντων των <classname>Grid</classname> και <classname>Window</classname>. Αν διαδοθεί, το κείμενο που γράφετε θα εμφανιστεί στην <classname>Label</classname> πάνω από την <classname>Entry</classname>.Όποτε πατάτε ή απελευθερώνετε ένα πλήκτρο, εκπέμπεται ένα συμβάν. Μπορείτε να συνδέσετε έναν χειριστή σήματος για να επεξεργαστεί τέτοια συμβάντα.Γιατί χρησιμοποιούμε τη <application>gtkmm</application> αντί για το GTK+;Αναφορά γραφικού συστατικούΗ Widget::on_expose_event() αντικαταστάθηκε από Widget::on_draw(), που υποθέτει ότι το cairomm χρησιμοποιείται για σχεδίαση, μέσα από την παρεχόμενη <classname>Cairo::Context</classname> και δεν σας ζητά να καλέσετε την <methodname>Cairo::Context::clip()</methodname>.Γραφικά συστατικάΓραφικά συστατικά χωρίς X-WindowsΓραφικά συστατικά και ChildAnchorsΤα γραφικά συστατικά τακτοποιούνται μέσα στα γραφικά συστατικά του περιέκτη όπως σκελετοί (frames) και σημειωματάρια, σε μια ιεραρχία των γραφικών συστατικών μέσα σε γραφικά συστατικά. Μερικά από αυτά τα γραφικά συστατικά του περιέκτη όπως το <classname>Gtk::Grid</classname>, δεν είναι ορατά - υπάρχουν μόνο για τακτοποίηση άλλων γραφικών συστατικών. Να κάποιο παράδειγμα κώδικα που προσθέτει 2 γραφικά συστατικά <classname>Gtk::Button</classname> σε ένα γραφικό συστατικό περιέκτη <classname>Gtk::Box</classname>: <placeholder-1/> και να πώς προστίθεται το <classname>Gtk::Box</classname>, που περιέχει αυτά τα κουμπιά, σε ένα <classname>Gtk::Frame</classname>, που έχει ένα ορατό σκελετό (frame) και τίτλο: <placeholder-2/>Με την <function>_WRAP_METHOD()</function> είναι επίσης δυνατό να τοποθετηθεί η επιστροφή της συσκευασμένης συνάρτησης C (αν έχει μία) σε μια παράμετρο εξόδου της μεθόδου C++ αντί να κάνετε τη μέθοδο C++ να επιστρέψει επίσης μια τιμή όπως κάνει η συνάρτηση C. Για να το κάνετε αυτό, συμπεριλάβετε απλά την παράμετρο εξόδου στον κατάλογο παραμέτρων μεθόδου C++ προσαρτώντας μια <literal>{OUT}</literal> στο όνομα παραμέτρου εξόδου. Για παράδειγμα, αν η <function>gtk_widget_get_request_mode()</function> δηλώνεται ως ακολούθως: <placeholder-1/> Και έχοντας ορίσει στη μέθοδο C++ μια παράμετρο εξόδου είναι επιθυμητό αντί να επιστραφεί ένας <type>SizeRequestMode</type>, κάτι όπως το παρακάτω να χρησιμοποιηθεί: <placeholder-2/> Η <literal>{OUT}</literal> προσαρτημένη στο όνομα της παραμέτρου εξόδου <parameter>mode</parameter> λέει στην <command>gmmproc</command> να βάλει την επιστροφή της συνάρτησης C σε αυτήν την παράμετρο εξόδου. Σε αυτήν την περίπτωση, όμως, μια απαραίτητη μακροεντολή αρχικοποίησης όπως η ακόλουθη μπορεί επίσης να πρέπει να οριστεί: <placeholder-3/> που μπορεί επίσης να γραφτεί ως: <placeholder-4/>Με το Cairo, η ίδια συνάρτηση χρησιμοποιείται για σχεδίαση τόξων, κύκλων ή ελλείψεων: <methodname>Cairo::Context::arc()</methodname>. Αυτή συνάρτηση παίρνει πέντε ορίσματα. Τα πρώτα δύο είναι οι συντεταγμένες του κεντρικού σημείου του τόξου, το τρίτο όρισμα είναι η ακτίνα του τόξου και τα τελευταία δυο ορίσματα ορίζουν την αρχή και τη γωνία τέλους του τόξου. Όλες οι γωνίες ορίζονται σε ακτίνια, έτσι η σχεδίαση ενός κύκλου είναι η ίδια με τη σχεδίαση ενός τόξου από 0 έως 2 * M_PI ακτίνια. Μια γωνία 0 είναι η κατεύθυνση του θετικού άξονα Χ (στον χώρο του χρήστη). Μια γωνία M_PI/2 ακτίνια (90 μοίρες) είναι στην κατεύθυνση του θετικού άξονα Υ (στον χώρο του χρήστη). Οι γωνίες αυξάνουν στην κατεύθυνση από τον θετικό άξονα Χ προς τον θετικό άξονα Υ. Έτσι, με τον προεπιλεγμένο πίνακα μετασχηματισμού, οι γωνίες αυξάνουν με δεξιόστροφη κατεύθυνση. (Να θυμάστε ότι θετικός άξονας Υ δείχνει προς τα κάτω.)Εργασία με τον πηγαίο κώδικα gtkmmΣυσκευασία των παραμέτρων <classname>GList*</classname> και <classname>GSList*</classname>: Πρώτα, χρειάζεστε να ανακαλύψετε ποια αντικείμενα περιέχονται στο πεδίο δεδομένων του καταλόγου για κάθε στοιχείο, συνήθως διαβάζοντας την τεκμηρίωση για τη συνάρτηση C. Ο κατάλογος μπορεί τότε να συσκευαστεί από έναν τύπο <classname>std::vector</classname>. Για παράδειγμα, <code>std::vector&lt; Glib::RefPtr&lt;Gdk::Pixbuf&gt; &gt;</code>. Μπορεί να χρειαστείτε να ορίσετε έναν τύπο χαρακτηριστικών για να ορίσετε πώς οι τύποι C και C++ πρέπει να μετατραπούν.Η συσκευασία <classname>GList*</classname> και <classname>GSList*</classname> επιστρέφει τύπους: Πρέπει να βρείτε αν ο καλών πρέπει να ελευθερώσει τη λίστα και αν πρέπει να απελευθερώσει τα στοιχεία στη λίστα, διαβάζοντας πάλι την τεκμηρίωση της συνάρτησης C. Με αυτήν την πληροφορία μπορείτε να διαλέξετε την ιδιοκτησία (καμία, ρηχή ή βαθιά) για τον κανόνα μετατροπής m4, που θα πρέπει προφανώς να βάλετε άμεσα στο αρχείο .hg, επειδή η ιδιοκτησία εξαρτάται από τη συνάρτηση παρά από τον τύπο. Για παράδειγμα: <placeholder-1/>Συσκευασία βιβλιοθηκών C με gmmprocΕγγραφή χειριστών σημάτωνΣυγγραφή των vfuncs .defsΣήματα συμβάντος ΧΤα συμβάντα Χ περιγράφονται πιο λεπτομερώς στην ενότητα <link linkend="sec-xeventsignals">Σήματα συμβάντων Χ</link> στο παράρτημα.Τα συμβάντα Χ διαφέρουν με κάποιους τρόπους από άλλα σήματα. Αυτές οι διαφορές περιγράφονται στην ενότητα <link linkend="sec-xeventsignals">Σήματα συμβάντων Χ</link> στο παράρτημα. Εδώ, θα χρησιμοποιήσουμε συμβάντα πληκτρολογίου για την εμφάνιση του τρόπου χρήσης των συμβάντων Χ σε ένα πρόγραμμα.Ναι, αυτό είναι σωστό: ένα παράθυρο μπορεί να περιέχει το πολύ ένα γραφικό συστατικό. Πώς, τότε, μπορούμε να χρησιμοποιούμε ένα παράθυρο για ο,τιδήποτε χρήσιμο; Τοποθετώντας έναν περιέκτη πολλαπλού θυγατρικού στο παράθυρο. Τα πιο χρήσιμα γραφικά συστατικά περιεκτών είναι οι <classname>Gtk::Grid</classname> και <classname>Gtk::Box</classname>.Μπορεί να αντιμετωπίσετε μερικά προβλήματα στη βιβλιοθήκη που συσκευάζετε, ιδιαίτερα αν είναι ένα νέο έργο. Ιδού μερικά συνηθισμένα προβλήματα με λύσεις.Δεν υπάρχει εγγύηση ότι θα πάρετε το <literal>Gtk::SizeRequestMode</literal> που ζητήσατε. Συνεπώς και οι τέσσερις μέθοδοι της <methodname>get_preferred_xxx_vfunc()</methodname> πρέπει να επιστρέψουν λογικές τιμές.Μπορείτε να ρυθμίσετε τη θέση του χωρίσματος χρησιμοποιώντας τη μέθοδο <methodname>set_position()</methodname> και θα χρειαστείτε προφανώς να το κάνετε.Μπορείτε επίσης να μετατρέψετε σε έναν παράγωγο τύπο, αλλά η σύνταξη είναι λίγο διαφορετική από ότι με έναν κανονικό δείκτη.Μπορείτε επίσης να συνδέσετε τα σήματα <classname>CellRenderer</classname> στην αναγνώριση ενεργειών χρήστη. Για παράδειγμα:Μπορείτε επίσης να ορίσετε έναν χειριστή σήματος όταν καλείτε την <methodname>ActionGroup::add()</methodname>. Αυτός ο χειριστής σήματος θα κληθεί όταν η ενέργεια ενεργοποιηθεί μέσα από είτε το στοιχείο μενού είτε από ένα κουμπί εργαλειοθήκης.Μπορείτε επίσης να χρησιμοποιήσετε την <methodname>get_tag_table()</methodname> για να πάρετε και ίσως να τροποποιήσετε στη <classname>TextBuffer</classname>, την προεπιλεγμένη <classname>TagTable</classname> αντί για δημιουργία μιας σαφώς.Μπορείτε να εφαρμόσετε περισσότερες από μία <classname>Tag</classname> στο ίδιο κείμενο, χρησιμοποιώντας την <methodname>apply_tag()</methodname> περισσότερο από μια φορά, ή χρησιμοποιώντας την <methodname>insert_with_tags()</methodname>. Οι <classname>Tag</classname>s μπορεί να ορίζουν διαφορετικές τιμές για τις ίδιες ιδιότητες, αλλά μπορείτε να επιλύσετε αυτές τις συγκρούσεις χρησιμοποιώντας <methodname>Tag::set_priority()</methodname>.Μπορείτε να δομήσετε αρκετές ενότητες ορίζοντας τη μεταβλητή <varname>modules</varname> σε ένα μεταπακέτο, π.χ. <literal>meta-gnome-core</literal>, ή καταχωρίζοντας περισσότερα από ένα ονόματα ενοτήτων. Η μεταβλητή <varname>modules</varname> καθορίζει ποιες ενότητες θα δομηθούν, όταν δεν ορίζετε ρητά τίποτα στη γραμμή εντολών. Μπορείτε πάντα να δομήσετε μια διαφορετική ομάδα ενοτήτων αργότερα ορίζοντας την στη γραμμή εντολών (π.χ. <command>jhbuild build gtkmm</command>).Μπορείτε να μετατρέψετε μια <classname>RefPtr</classname>s σε βασικούς τύπους, ακριβώς όπως με τους κανονικούς δείκτες.Μπορείτε να αντιγράψετε <classname>RefPtr</classname>s, ακριβώς όπως σε κανονικούς δείκτες. Αλλά αντίθετα με τους κανονικούς δείκτες, δεν χρειάζεται να ανησυχείτε για τη διαγραφή του υποκείμενου στιγμιότυπου.Μπορείτε να δημιουργήσετε μια νέα <classname>RecentManager</classname>, αλλά μάλλον θα θέλετε να χρησιμοποιήσετε απλά την προεπιλεγμένη. Μπορείτε να κάνετε μια αναφορά στην προεπιλεγμένη <classname>RecentManager</classname> με την <methodname>get_default()</methodname>.Μπορείτε να αποαναφέρετε έναν έξυπνο δείκτη με τον τελεστή -&gt;, για να καλέσετε τις μεθόδους του υποκείμενου στιγμιότυπου, ακριβώς όπως ένας κανονικός δείκτης.Μπορείτε να αφαιρέσετε την αναφορά από τον επαναλήπτη για να πάρετε τη γραμμή:Μπορείτε να σχεδιάσετε πολύ προχωρημένα σχήματα χρησιμοποιώντας το Cairo, αλλά οι μέθοδοι για να γίνει αυτό είναι αρκετά βασικές. Το Cairo παρέχει μεθόδους για σχεδίαση ευθειών γραμμών, καμπύλων γραμμών και τόξων (συμπεριλαμβανομένων κύκλων). Αυτά τα βασικά σχήματα μπορούν να συνδυαστούν για να δημιουργήσουν πιο σύνθετα σχήματα και μονοπάτια που μπορούν να γεμίσουν με συμπαγή χρώματα, διαβαθμίσεις, μοτίβα και άλλα. Επιπλέον, το Cairo μπορεί να εκτελέσει σύνθετους μετασχηματισμούς, να συνθέσει εικόνες και να αποδώσει εξομαλυμένο κείμενο.Μπορείτε να ενσωματώσετε γραφικά συστατικά, όπως <classname>Gtk::Button</classname>s, στο κείμενο. Κάθε τέτοιο θυγατρικό γραφικό συστατικό χρειάζεται μια <classname>ChildAnchor</classname>. Οι ChildAnchors συσχετίζονται με την <classname>iterators</classname>. Για παράδειγμα, για να δημιουργήσετε μια θυγατρική αγκύρωση σε μια ειδική θέση, χρησιμοποιήστε <methodname>Gtk::TextBuffer::create_child_anchor()</methodname>:Μπορείτε να τροποποιήσετε την πολιτική ενημέρωσης χρησιμοποιώντας τη μέθοδο <methodname>set_update_policy()</methodname>, ορίζοντας ή <literal>Gtk::UPDATE_ALWAYS</literal> ή <literal>Gtk::UPDATE_IF_VALID</literal>. Το <literal>Gtk::UPDATE_ALWAYS</literal> προκαλεί το <classname>SpinButton</classname> να αγνοήσει σφάλματα που παρουσιάστηκαν κατά τη μετατροπή του κειμένου στο πλαίσιο καταχώρισης σε μια αριθμητική τιμή. Αυτή η ρύθμιση επίσης επιτρέπει στην <classname>SpinButton</classname> να δεχτεί μη αριθμητικές τιμές. Μπορείτε να εξαναγκάσετε μια άμεση ενημέρωση χρησιμοποιώντας τη μέθοδο <methodname>update()</methodname>.Μπορείτε να ορίσετε τις ιδιότητες <emphasis>περιθωρίου</emphasis> και <emphasis>επέκτασης</emphasis> των θυγατρικών <classname>Widget</classname>s ώστε να ελέγχουν το διάκενό τους και τη συμπεριφορά τους, όταν το πλέγμα αυξομειώνεται.Μπορείτε να ορίσετε τιμή κουμπιού αυξομείωσης χρησιμοποιώντας τη μέθοδο <methodname>set_value()</methodname> και να την ανακτήσετε με <methodname>get_value()</methodname>.Μπορείτε να ορίσετε μία <classname>Gtk::TreeModel</classname>, όταν κατασκευάζετε την <classname>Gtk::TreeView</classname>, ή μπορείτε να χρησιμοποιήσετε τη μέθοδο <methodname>set_model()</methodname>, ως εξής:Μπορείτε να ορίσετε ένα όνομα για την <classname>Tag</classname>, όταν χρησιμοποιείτε τη μέθοδο <methodname>create()</methodname>, αλλά δεν είναι απαραίτητο.Μπορείτε να σταματήσετε τη μέθοδο λήξης χρόνου επιστρέφοντας <literal>false</literal> από τον χειριστή σήματός σας. Συνεπώς, αν θέλετε η μέθοδός σας να καλείται επανειλημμένα, θα πρέπει να επιστρέψετε <literal>true</literal>.Μπορείτε έπειτα να συνδεθείτε με το κατάλληλο "επεξεργασμένο" σήμα. Για παράδειγμα, συνδεθείτε στις <methodname>Gtk::CellRendererText::signal_edited()</methodname>, ή <methodname>Gtk::CellRendererToggle::signal_toggled()</methodname>. Αν η στήλη περιέχει περισσότερες από μία <classname>CellRenderer</classname>, τότε θα απαιτηθεί η χρήση της <methodname>Gtk::TreeView::get_column()</methodname> και μετά η κλήση της <methodname>get_cell_renderers()</methodname> σε αυτήν την στήλη προβολής.Μπορείτε έπειτα να το συνδέσετε με το σήμα χρησιμοποιώντας την ίδια σύνταξη που χρησιμοποιείται όταν συνδέεται τα σήματα <application>gtkmm</application>. Για παράδειγμα, <placeholder-1/>Μπορείτε έπειτα να χρησιμοποιήσετε τη μέθοδο <methodname>get_iter()</methodname> αργότερα για να δημιουργήσετε έναν επαναλήπτη για τη νέα θέση της <classname>Mark</classname>.Μπορείτε να χρησιμοποιήσετε την <application>Glade</application> για την διευθέτηση προσαρμοσμένων γραφικών συστατικών που παράγονται από τις κλάσεις γραφικών συστατικών <application>gtkmm</application>. Αυτό κρατά τον κώδικά σας οργανωμένο και ενθυλακωμένο. Φυσικά δεν θα δείτε την ακριβή εμφάνιση και τις ιδιότητες του παραγόμενου γραφικού συστατικού σας στην <application>Glade</application>, αλλά μπορείτε να ορίσετε τη θέση του και τα θυγατρικά γραφικά συστατικά καθώς και τις ιδιότητες της βασικής κλάσης του <application>gtkmm</application>.Μπορείτε να χρησιμοποιήσετε APIs C που δεν έχουν ακόμα βολικές διεπαφές C++. Δεν είναι γενικά πρόβλημα να χρησιμοποιήσετε APIs C από C++ και τη <application>gtkmm</application> βοηθά δίνοντας πρόσβαση στο υποκείμενο αντικείμενο C και παρέχοντας έναν εύκολο τρόπο δημιουργίας αντικειμένου συσκευαστή C++ από ένα αντικείμενο C, με την προϋπόθεση ότι η API C βασίζεται επίσης στο σύστημα GObject.Μπορείτε να χρησιμοποιήσετε τη μέθοδο <methodname>append_column()</methodname> για να πείτε στην προβολή ότι θα πρέπει να εμφανίσει συγκεκριμένες στήλες του προτύπου, σε μια συγκεκριμένη σειρά, με έναν συγκεκριμένο τίτλο στήλης.Μπορείτε να χρησιμοποιήσετε τη <methodname>operator[]</methodname> για να αντικαταστήσει τη λήψη των δεδομένων για μια συγκεκριμένη στήλη σε μια γραμμή, ορίζοντας την <classname>TreeModelColumn</classname> που χρησιμοποιήθηκε στη δημιουργία του προτύπου.Μπορείτε να χρησιμοποιήσετε τη <methodname>operator[]</methodname> για να αντικαταστήσει τον ορισμό των δεδομένων για μια συγκεκριμένη στήλη στη γραμμή, ορίζοντας την <classname>TreeModelColumn</classname> που χρησιμοποιήθηκε στη δημιουργία του προτύπου.Μπορείτε να χρησιμοποιήσετε τη μέθοδο <methodname>toggled()</methodname> για εναλλαγή του κουμπιού, αντί να το εξαναγκάσετε να είναι πάνω ή κάτω: Αυτό εναλλάσσει την κατάσταση του κουμπιού και προκαλεί την εκπομπή του σήματος <literal>toggled</literal>.Μπορείτε συνήθως να προσποιηθείτε ότι η <classname>Gtk::Clipboard</classname> είμαι μια singleton. Μπορείτε να πάρετε ένα προεπιλεγμένο στιγμιότυπο προχείρου με <methodname>Gtk::Clipboard::get()</methodname>. Αυτό είναι προφανώς το μόνο πρόχειρο που θα χρειαστείτε ποτέ.Μπορείτε να δηλώσετε απλά ότι το σήμα ως μια δημόσια μεταβλητή μέλους, αλλά μερικά άτομα το βρίσκουν άσχημο και προτιμούν να το κάνουν διαθέσιμο μέσα από μια μέθοδο στοιχείου πρόσβασης, ως εξής: <placeholder-1/>Μπορείτε έπειτα να ενθυλακώσετε τον χειρισμό των θυγατρικών γραφικών συστατικών στον κατασκευαστή της παράγωγης κλάσης, ίσως χρησιμοποιώντας την <methodname>get_widget()</methodname> ή την <methodname>get_widget_derived()</methodname> πάλι. Για παράδειγμα, <placeholder-1/>Δεν χρειάζεται πάντα να καλέσετε τη γονική μέθοδο· υπάρχουν φορές που μπορεί να μην το θέλετε. Σημειώστε ότι, καλούμε τη γονική μέθοδο <emphasis>αφού</emphasis> γράψουμε "Hello World", αλλά μπορούμε να την έχουμε καλέσει πριν. Σε αυτό το απλό παράδειγμα, δεν πειράζει πολύ, αλλά υπάρχουν φορές που πειράζει. Με σήματα, δεν είναι τόσο εύκολη η αλλαγή λεπτομερειών όπως αυτή και μπορείτε να κάνετε κάτι εδώ που δεν μπορείτε να κάνετε καθόλου με συνδεμένους χειριστές σήματος: μπορείτε να καλέσετε τη γονική μέθοδο στο <emphasis>μέσο</emphasis> του προσαρμοσμένου κώδικά σας.Δεν έχετε τρόπο λήψης μιας γυμνής <classname>Gdk::Pixbuf</classname>. Στο παράδειγμα, η <varname>pixbuf</varname> είναι ένας έξυπνος δείκτης, έτσι μπορείτε να το κάνετε, περίπου σαν έναν κανονικό δείκτη: <placeholder-1/>Μπορείτε να προσθέσετε μια προσαρμοσμένη καρτέλα στον διάλογο εκτύπωσης: <placeholder-1/>Μπορεί να αναρωτιέστε πώς γίνεται η <application>gtkmm</application> να κάνει χρήσιμη εργασία, ενώ είναι αδρανής. Ευτυχώς, έχετε πολλές επιλογές. Χρησιμοποιώντας τις ακόλουθες μεθόδους μπορείτε να δημιουργήσετε μια μέθοδο ορίου χρόνου που θα καλείται κάθε λίγα χιλιοστά του δευτερολέπτου.Μπορείτε επίσης να παράξετε κλάσεις μη γραφικού συστατικού από Gtk::Object έτσι ώστε να μπορεί να χρησιμοποιηθεί χωρίς <classname>Glib::RefPtr</classname>. Για παράδειγμα, μπορούν έπειτα να αρχικοποιηθούν με <function>Gtk::manage()</function> ή στη στοίβα ως μεταβλητή μέλους. Αυτό είναι βολικό, αλλά θα πρέπει να χρησιμοποιήσετε αυτό μόνον όταν είσαστε σίγουροι ότι η αληθινή μέτρηση αναφορών δεν χρειάζεται. Το θεωρούμε χρήσιμο για γραφικά συστατικά.Μπορεί να εκπλαγείτε μαθαίνοντας ότι η <application>gtkmm</application> δεν χρησιμοποιεί τη <classname>std::string</classname> στις διεπαφές της. Αντίθετα χρησιμοποιεί τη <classname>Glib::ustring</classname>, που είναι τόσο παρόμοια και διακριτική που θα μπορούσατε στην πραγματικότητα να προσποιηθείτε ότι κάθε <classname>Glib::ustring</classname> είναι μία <classname>std::string</classname> και να αγνοήστε το υπόλοιπο αυτής της ενότητας. Αλλά διαβάστε, αν θέλετε να χρησιμοποιήσετε διαφορετικές γλώσσες από τα αγγλικά στην εφαρμογή σας.Μπορεί να χρειαστείτε να αντιδράσετε σε κάθε αλλαγή της επιλογής στο ComboBox, για παράδειγμα να ενημερώσετε άλλα γραφικά συστατικά. Για να γίνει αυτό, θα πρέπει να χειριστείτε το σήμα <literal>changed</literal>. Για παράδειγμα:Μπορεί να μην προβλέψετε την ανάγκη υποστήριξης πρόσθετων γλωσσών, αλλά δεν μπορείτε ποτέ να το αποκλείσετε. Φυσικά, είναι ευκολότερο να αναπτύξετε την εφαρμογή κατάλληλα από την αρχή αντί να την τροποποιήσετε αργότερα.Μπορεί ενίοτε να βρείτε χρήσιμο τον χειρισμό συμβάντων Χ, όταν υπάρχει κάτι που δεν μπορείτε να πραγματοποιήσετε με κανονικά σήματα. Η <classname>Gtk::Button</classname>, για παράδειγμα, δεν στέλνει συντεταγμένες δείκτη ποντικιού με το σήμα της <literal>clicked</literal>, αλλά μπορείτε να χειριστείτε την <literal>button_press_event</literal>, αν χρειαστείτε αυτήν την πληροφορία. Τα συμβάντα Χ χρησιμοποιούνται επίσης συχνά για χειρισμό των πατημάτων πλήκτρου.Μπορείτε έπειτα να χειριστείτε στην <classname>ToolButton</classname> το σήμα <literal>clicked</literal>. Εναλλακτικά, θα μπορείτε να επιτρέψετε στο στοιχείο να μετακινηθεί σε ένα άλλο γραφικό συστατικό, καλώντας <methodname>Gtk::ToolPalette::add_drag_dest()</methodname> και έπειτα χρησιμοποιώντας την <methodname>Gtk::ToolPalette::get_drag_item()</methodname> στον χειριστή σήματος <literal>drag_data_received</literal> του άλλου γραφικού συστατικού.Μπορεί να θέλετε να συνδέσετε πρόσθετα δεδομένα με κάθε γραμμή. Αν συμβαίνει αυτό, απλά προσθέστε το ως μια στήλη προτύπου, αλλά μην το προσθέσετε στην προβολή.Μπορεί να θέλετε να ειδοποιηθεί όποτε ο χρήστης πληκτρολογεί σε ένα γραφικό συστατικό καταχώρισης κειμένου. Η <classname>Gtk::Entry</classname> παρέχει δύο σήματα, <literal>activate</literal> και <literal>changed</literal>, για αυτόν τον σκοπό. Το <literal>activate</literal> εκπέμπεται όταν ο χρήστης πατά το πλήκτρο εισαγωγής στο γραφικό συστατικό καταχώρισης κειμένου· το <literal>changed</literal> εκπέμπεται, όταν το κείμενο στο γραφικό συστατικό αλλάζει. Μπορείτε να χρησιμοποιήσετε αυτά, για παράδειγμα, για να επικυρώσετε ή να φιλτράρετε το κείμενο που πληκτρολογεί ο χρήστης. Η μετακίνηση της εστίασης του πληκτρολογίου σε ένα άλλο γραφικό συστατικό μπορεί επίσης να δώσει σήμα ότι ο χρήστης έχει τελειώσει την εισαγωγή κειμένου. Το σήμα <literal>focus_out_event</literal> που η <classname>Gtk::Entry</classname> κληρονομεί από την <classname>Gtk::Widget</classname> μπορεί να σας ειδοποιήσει όταν αυτό συμβαίνει. Η ενότητα <link linkend="sec-comboboxentry">Σύνθετο πλαίσιο με μια καταχώριση</link> περιέχει παράδειγμα προγραμμάτων που χρησιμοποιούν αυτά τα σήματα.Μπορεί να θέλετε να συμπεριλάβετε πρόσθετα πηγαία αρχεία που δεν θα δημιουργηθούν από την <command>gmmproc</command> και από τα αρχεία <filename>.hg</filename> και <filename>.ccg</filename>. Μπορείτε απλά να τα βάλετε στον κατάλογο <filename>libsomething/libsomethingmm</filename> και να τα αναφέρετε στο <filename>Makefile.am</filename> στις μεταβλητές <varname>files_extra_h</varname> και <varname>files_extra_cc</varname>.Μπορεί να θέλετε να επαναχρησιμοποιήσετε την τεκμηρίωση που υπάρχει για τη βιβλιοθήκη C που συσκευάζετε. Οι βιβλιοθήκες C τεχνοτροπίας GTK χρησιμοποιούν τυπικά gtk-doc και συνεπώς έχουν σχόλια πηγαίου κώδικα μορφοποιημένα για gtk-doc και κάποια πρόσθετη τεκμηρίωση σε αρχεία .sgml και .xml. Το σενάριο docextract_to_xml.py, από τον κατάλογο <filename>tools/defs_gen</filename> του glibmm, μπορεί να διαβάσει αυτά τα αρχεία και να δημιουργήσει ένα αρχείο .xml που μπορεί να χρησιμοποιήσει την <command>gmmproc</command> για να δημιουργήσει σχόλια doxygen. Η <command>gmmproc</command> θα προσπαθήσει ακόμα να μετασχηματίσει την τεκμηρίωση για να την κάνει πιο κατάλληλη για μια API C++.Πρέπει να καλέσετε τον κατασκευαστή της βασικής κλάσης στον κατάλογο αρχικοποίησης, δίνοντας τον δείκτη C. Για παράδειγμα, <placeholder-1/>Πρέπει να επεξεργαστείτε τον πηγαίο κώδικα του δικού σας εργαλείου <filename>generate_extra_defs</filename> για να δημιουργήσετε το <filename>.defs</filename> για τους τύπους GObject C που θέλετε να συσκευάσετε. Στο πηγαίο δένδρο σκελετού, το αρχείο πηγής ονομάζεται <filename>codegen/extradefs/generate_extra_defs_skeleton.cc</filename>. Αν δεν έχει ήδη γίνει, το αρχείο πρέπει να μετονομαστεί, με το βασικό όνομα της νέας σύνδεσης που αντικαθίσταται με το δεσμευτικό θέσης <varname>skeleton</varname>. Το αρχείο <filename>codegen/Makefile.am</filename> πρέπει επίσης να αναφέρει το νέο πηγαίο όνομα αρχείου.Πρέπει να ορίσετε μια προαιρετική παράμετρο <literal>after = false</literal> στην κλήση στο <literal>signal_command_line().connect()</literal>, επειδή ο χειριστής σήματός σας πρέπει να κληθεί πριν τον προεπιλεγμένο χειριστή σήματος. Πρέπει επίσης να καλέσετε την <methodname>Gio::Application::activate()</methodname> στον χειριστή σήματος, εκτός και θέλετε η εφαρμογή σας να εξέλθει χωρίς την εμφάνιση του κυρίως παραθύρου. (η <classname>Gio::Application</classname> είναι μια βασική κλάση της <classname>Gtk::Application</classname>.)Χρειάζεται να ορίσετε τα χαρακτηριστικά της <classname>Alignment</classname> στον κατασκευαστή, ή τη μέθοδο <methodname>set()</methodname>. Συγκεκριμένα, δεν θα παρατηρήσετε σημαντική επίδραση εκτός και ορίσετε έναν αριθμό διαφορετικό από 1.0 για τις παραμέτρους <literal>xscale</literal> και <literal>yscale</literal>, επειδή 1.0 σημαίνει απλά ότι το θυγατρικό γραφικό συστατικό θα επεκταθεί για να γεμίσει όλον τον διαθέσιμο χώρο.Δεν ξέρετε ποτέ πόσο χώρο θα πάρει μια συμβολοσειρά στην οθόνη όταν μεταφραστεί. Μπορεί πιθανόν να είναι διπλάσια από το μέγεθος της αρχικής αγγλικής συμβολοσειράς. Ευτυχώς, τα περισσότερα γραφικά συστατικά της <application>gtkmm</application> θα επεκταθούν στον χρόνο εκτέλεσης στο απαιτούμενο μέγεθος.Δεν θα χρειαστείτε ποτέ να προσαρτήσετε έναν χειριστή σε αυτό το σήμα, εκτός και γράφετε έναν νέο τύπο γραφικού συστατικού περιοχής.Θα πρέπει να αποφύγετε τον αριθμητικό δείκτη τεχνοτροπίας C και συναρτήσεις όπως strlen(). Σε UTF-8, κάθε χαρακτήρας μπορεί να χρειαστεί οπουδήποτε από 1 έως 6 ψηφιολέξεις, έτσι δεν είναι δυνατό να θεωρήσετε ότι η επόμενη ψηφιολέξη είναι ένας άλλος χαρακτήρας. Η <classname>Glib::ustring</classname> ασχολείται με τις λεπτομέρειες αυτού για σας, έτσι μπορείτε να χρησιμοποιήσετε μεθόδους όπως Glib::ustring::substr(), ενώ σκεφτόσαστε ακόμα χαρακτήρες αντί για ψηφιολέξεις.Θα πρέπει να αποφεύγετε κρυπτογραφικές συντομεύσεις, αργκό, ή φρασεολογία. Είναι συνήθως δύσκολο να μεταφραστούν και είναι συχνά δύσκολες ακόμα και για μητρικούς ομιλητές να τις κατανοήσουν. Για παράδειγμα, προτιμήστε "application" από "app"Θα πρέπει να αποφύγετε να συμπεριλάβετε την κεφαλίδα C της κεφαλίδας σας C++, για να αποφύγετε τη μόλυνση του καθολικού χώρου ονόματος και την εξαγωγή περιττών δημόσιων API. Αλλά θα χρειαστείτε να συμπεριλάβετε τις απαραίτητες κεφαλίδες C από το αρχείο σας .ccg.Θα πρέπει να είστε πολύ προσεκτικοί κατά την εγκατάσταση σε τυπικά προθέματα συστήματος όπως <filename>/usr</filename>. Οι διανομές Λίνουξ εγκαθιστούν πακέτα λογισμικού στο <filename>/usr</filename>, έτσι η εγκατάσταση ενός πηγαίου πακέτου σε αυτό το πρόθεμα μπορεί να αλλοιώσει ή να συγκρουστεί με το εγκατεστημένο λογισμικό χρησιμοποιώντας το σύστημα διαχείρισης πακέτου της διανομής σας. Ιδανικά, θα πρέπει να χρησιμοποιήσετε ένα ξεχωριστό πρόθεμα για όλο το λογισμικό που εγκαθιστάτε από την πηγή.Δεν θα πρέπει να δηλώσετε αυτούς τους τύπους εσείς. Θα πρέπει αντίθετα να χρησιμοποιήσετε τον τυπικό περιέκτη C++ που προτιμάτε. Το glibmm θα το μετατρέψει για σας. Να μερικοί από αυτούς τους ενδιάμεσους τύπους: <placeholder-1/>Θα πρέπει να αποθηκεύσετε την επιλεγμένη <classname>Gtk::PageSetup</classname> έτσι ώστε να μπορείτε να την χρησιμοποιήσετε πάλι, αν ο διάλογος διαμόρφωσης σελίδας εμφανιστεί πάλι.Θα πρέπει έπειτα να αλλάξετε τύπο σε <classname>Gtk::CellRenderer*</classname> στο συγκεκριμένο <classname>CellRenderer</classname> που περιμένετε, έτσι μπορείτε να χρησιμοποιήσετε ειδικές API.Ορίζετε την <classname>ColumnRecord</classname> όταν δημιουργείτε το πρότυπο, ως εξής:Χρειάζεστε ακόμα κώδικα C++ για να αντιμετωπίσετε αλλαγές διεπαφής χρήστη που προκλήθηκαν από ενέργειες χρήστη, αλλά η χρήση της <application>Gtk::Builder</application> για τη διάταξη γραφικού συστατικού επιτρέπει να εστιάσετε στην υλοποίηση αυτής της λειτουργίας.Θα χρησιμοποιήσουμε τυπικά αυτή τη μακροεντολή όταν η κλάση παράγεται ήδη από την Gtk::Object. Για παράδειγμα, θα την χρησιμοποιήσετε όταν συσκευάζετε ένα γραφικό συστατικό GTK+, επειδή η Gtk::Widget παράγεται από Gtk::Object.Έχετε προφανώς σημειώσει ότι τα παράθυρα <application>gtkmm</application> φαίνονται "ελαστικά" - μπορούν συνήθως να τεντωθούν με πολλούς διαφορετικούς τρόπους. Αυτό οφείλεται στο σύστημα <emphasis>συσκευασίας γραφικού συστατικού</emphasis>.Η εφαρμογή σας δεν χρειάζεται να περιμένει για τις λειτουργίες του προχείρου, ιδιαίτερα μεταξύ του χρόνου όταν ο χρήστης επιλέγει αντιγραφή και έπειτα αργότερα επιλέγει επικόλληση. Οι περισσότερες μέθοδοι <classname>Gtk::Clipboard</classname> παίρνουν <classname>sigc::slot</classname>s που ορίζουν μεθόδους επανάκλησης. Όταν η <classname>Gtk::Clipboard</classname> είναι έτοιμη, θα καλέσει αυτές τις μεθόδους, είτε παρέχοντας τα ζητούμενα δεδομένα, είτε ζητώντας τα δεδομένα.Η επανάκληση θα δώσει τότε τα αποθηκευμένα δεδομένα, όταν ο χρήστης επιλέγει την επικόλληση δεδομένων. Για παράδειγμα:Η παραγόμενη κλάση σας πρέπει να έχει έναν κατασκευαστή που παίρνει έναν δείκτη στον υποκείμενο τύπο C και το στιγμιότυπο <classname>Gtk::Builder</classname>. Όλες οι σχετικές κλάσεις της <application>gtkmm</application> ορίζουν τύπο τον υποκείμενο τύπο τους της C ως <classname>BaseObjectType</classname> (<classname>Gtk::Dialog</classname> ορίζει τύπους <classname>BaseObjectType</classname> ως <type>GtkDialog</type>, για παράδειγμα).Η υπάρχουσα γνώση της C++ θα σας βοηθήσει με τη <application>gtkmm</application>, όπως θα έκανε με οποιαδήποτε βιβλιοθήκη. Εκτός και δηλωθεί αλλιώς, μπορείτε να περιμένετε οι κλάσεις της <application>gtkmm</application> να συμπεριφέρονται όπως οποιαδήποτε άλλη κλάση C++ και μπορείτε να περιμένετε να χρησιμοποιήσετε τις υπάρχουσες τεχνικές C++ με τις κλάσεις της <application>gtkmm</application>.Η υλοποίηση της μεθόδου <methodname>child_type_vfunc()</methodname> πρέπει να αναφέρει τον τύπο του γραφικού συστατικού που μπορεί να προστεθεί στον περιέκτη σας, αν δεν είναι ακόμα πλήρης. Αυτή είναι συνήθως η <methodname>Gtk::Widget::get_type()</methodname> που δείχνει ότι ο περιέκτης μπορεί να περιέχει οποιαδήποτε κλάση παράγεται από την <classname>Gtk::Widget</classname>. Αν ο περιέκτης μπορεί να μην περιέχει οποιαδήποτε περισσότερα γραφικά συστατικά, τότε αυτή η μέθοδος πρέπει να επιστρέψει <literal>G_TYPE_NONE</literal>.Η βιβλιοθήκη σας πρέπει να αρχικοποιηθεί πριν να μπορέσει να χρησιμοποιηθεί, για να καταχωρίσει τους νέους τύπους που κάνει διαθέσιμους. Επίσης, η βιβλιοθήκη C που συσκευάζετε μπορεί να έχει τη δικιά της συνάρτηση αρχικοποίησης που θα πρέπει να καλέσετε. Μπορείτε να το κάνετε σε μια συνάρτηση <function>init()</function> που μπορείτε να βάλετε στα κωδικοποιημένα με το χέρι αρχεία <filename>init.h</filename> και <filename>init.cc</filename>. Αυτή η συνάρτηση πρέπει να αρχικοποιήσει τις εξαρτήσεις σας (όπως η συνάρτηση C και η <application>gtkmm</application>) και να καλέσει τη δημιουργούμενη συνάρτηση <function>wrap_init()</function>. Για παράδειγμα: <placeholder-1/>_CLASS_BOXEDTYPE_CLASS_BOXEDTYPE( C++ class, C class, new function, copy function, free function )_CLASS_BOXEDTYPE_STATIC_CLASS_BOXEDTYPE_STATIC( C++ class, C class )_CLASS_GENERIC_CLASS_GENERIC( C++ class, C class )_CLASS_GOBJECT_CLASS_GOBJECT( C++ class, C class, C casting macro, C++ base class, C base class )_CLASS_GTKOBJECT_CLASS_GTKOBJECT( C++ class, C class, C casting macro, C++ base class, C base class )_CLASS_GTKOBJECT()_CLASS_INTERFACE_CLASS_INTERFACE( C++ class, C class, C casting macro, C interface struct, Base C++ class (optional), Base C class (optional) )_CLASS_OPAQUE_COPYABLE_CLASS_OPAQUE_COPYABLE( C++ class, C class, new function, copy function, free function )_CLASS_OPAQUE_REFCOUNTED_CLASS_OPAQUE_REFCOUNTED( C++ class, C class, new function, ref function, unref function )_CTOR_DEFAULT_DEFS()_IGNORE / _IGNORE_SIGNAL_IGNORE(C function name 1, C function name2, etc)_IGNORE_SIGNAL(C signal name 1, C signal name2, etc)_IMPLEMENTS_INTERFACE_IMPLEMENTS_INTERFACE()_IMPLEMENTS_INTERFACE(όνομα διεπαφής C++)_MEMBER_GET / _MEMBER_SET_MEMBER_GET(C++ name, C name, C++ type, C type)_MEMBER_GET(x, x, int, int)_MEMBER_GET_GOBJECT / _MEMBER_SET_GOBJECT_MEMBER_GET_GOBJECT(C++ name, C name, C++ type, C type)_MEMBER_GET_PTR / _MEMBER_SET_PTR_MEMBER_GET_PTR(C++ name, C name, C++ type, C type)_MEMBER_SET(C++ name, C name, C++ type, C type)_MEMBER_SET_GOBJECT(C++ name, C name, C++ type, C type)_MEMBER_SET_PTR(C++ name, C name, C++ type, C type)_PINCLUDE()_WRAP_CTOR_WRAP_ENUM_WRAP_ENUM_DOCS_ONLY_WRAP_GERROR_WRAP_METHOD_WRAP_METHOD( C++ method signature, C function name)_WRAP_METHOD_DOCS_ONLY_WRAP_METHOD_DOCS_ONLY(C function name)_WRAP_PROPERTY_WRAP_PROPERTY( όνομα ιδιότητας C, τύπος C++)_WRAP_SIGNAL_WRAP_SIGNAL( υπογραφή χειριστή σήματοςC++ , όνομα σήματος C)_WRAP_VFUNC_WRAP_VFUNC( υπογραφή μεθόδου C++, όνομα συνάρτησης C)adj-&gt;signal_value_changed().connect(sigc::bind&lt;MyPicture*&gt;(sigc::mem_fun(*this,
    &amp;cb_rotate_picture), picture));adjustment-&gt;signal_changed();και να το συνδέσετε στην προσαρμογή του γραφικού συστατικού κλίμακας όπως αυτό:και έπειταatkmmbinding_namebindtextdomain(GETTEXT_PACKAGE, PROGRAMNAME_LOCALEDIR);
bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
textdomain(GETTEXT_PACKAGE);boolbool DemoWindow::select_function(
    const Glib::RefPtr&lt;Gtk::TreeModel&gt;&amp; model,
    const Gtk::TreeModel::Path&amp; path, bool)
{
  const Gtk::TreeModel::iterator iter = model-&gt;get_iter(path);
  return iter-&gt;children().empty(); // only allow leaf nodes to be selected
}bool ExampleWindow::on_button_press_event(GdkEventButton* event)
{
  if( (event-&gt;type == GDK_BUTTON_PRESS) &amp;&amp;
      (event-&gt;button == 3) )
  {
    m_Menu_Popup-&gt;popup(event-&gt;button, event-&gt;time);
    return true; //It has been handled.
  }
  else
    return false;
}bool MyArea::on_draw(const Cairo::RefPtr&lt;Cairo::Context&gt;&amp; cr)
{
  Glib::RefPtr&lt;Gdk::Pixbuf&gt; image = Gdk::Pixbuf::create_from_file("myimage.png");
  // Draw the image at 110, 90, εκτός από το πιο εξωτερικό 10 pixels.
  Gdk::Cairo::set_source_pixbuf(cr, image, 100, 80);
  cr-&gt;rectangle(110, 90, image-&gt;get_width()-20, image-&gt;get_height()-20);
  cr-&gt;fill();
  return true;
}παράδειγμα κουμπιώνcairocairommcell.property_editable() = true;class HelloWorld : public Gtk::Window
{

public:
  HelloWorld()·
  virtual ~HelloWorld();

protected:
  //Signal handlers:
  virtual void on_button_clicked();

  //Member widgets:
  Gtk::Button m_button;
};class ModelColumns : public Gtk::TreeModelColumnRecord
{
public:

  ModelColumns()
    { add(m_col_text); add(m_col_number); }

  Gtk::TreeModelColumn&lt;Glib::ustring&gt; m_col_text;
  Gtk::TreeModelColumn&lt;int&gt; m_col_number;
};

ModelColumns m_Columns;class RadioButtons : public Gtk::Window
{
public:
    RadioButtons();

protected:
    Gtk::RadioButton m_rb1, m_rb2, m_rb3;
};

RadioButtons::RadioButtons()
  : m_rb1("button1"),
    m_rb2("button2"),
    m_rb3("button3")
{
    Gtk::RadioButton::Group group = m_rb1.get_group();
    m_rb2.set_group(group);
    m_rb3.set_group(group);
}class RadioButtons : public Gtk::Window
{
public:
    RadioButtons();
};

RadioButtons::RadioButtons()
{
    Gtk::RadioButton::Group group;
    Gtk::RadioButton *m_rb1 = Gtk::manage(
      new Gtk::RadioButton(group,"button1"));
    Gtk::RadioButton *m_rb2 = manage(
      new Gtk::RadioButton(group,"button2"));
      Gtk::RadioButton *m_rb3 = manage(
        new Gtk::RadioButton(group,"button3"));
}πατημένοconfigure.acσταθερή έκδοση (constversion)context-&gt;save();
context-&gt;translate(x, y);
context-&gt;scale(width / 2.0, height / 2.0);
context-&gt;arc(0.0, 0.0, 1.0, 0.0, 2 * M_PI);
context-&gt;restore();προσαρμοσμένη επανάκληση c (custom_c_callback)προσαρμοσμένος προεπιλεγμένος χειριστής (custom_default_handler)Προσαρμοσμένη εικονική συνάρτηση (custom_vfunc)επανάκληση προσαρμοσμένης εικονικής συνάρτησης (custom_vfunc_callback)παρωχημένοdisplay_message("Getting ready for i18n.");display_message(_("Getting ready for i18n."));doubleεισαγωγήαπαριθμήσειςΔημιουργία σφάλματος (errthrow)event_box.add(child_widget);σημαίες: Χρησιμοποιούνται μόνο για μεταφορά και απόθεση, αυτό καθορίζει αν τα δεδομένα μπορούν να μετακινηθούν σε άλλα γραφικά συστατικά και εφαρμογές, ή μόνο στα ίδια.συναρτήσειςg++ simple.cc -o simple `pkg-config gtkmm-3.0 --cflags --libs`gbooleangchar*gdk-pixbufgdoubleεγχειρίδιο λήψης κειμένου (gettext)gintglibglibmmΕπεξεργασία παραμέτρου gmmprocgnomemm_hellogtk.defsgtk_enums.defsgtk_methods.defsgtk_signals.defsgtk_vfuncs.defsgtkmmgtkmm-3.0 είναι το όνομα της τρέχουσας σταθερής API. Υπήρξε μια παλιότερη API που λεγότανε gtkmm-2-4 που εγκαθίσταται παράλληλα όταν είναι διαθέσιμη. Υπήρξαν πολλές εκδόσεις του gtkmm-2.4, όπως gtkmm 2.10 και θα υπάρξουν αρκετές εκδόσεις του gtkmm-3.0 API. Σημειώστε ότι το όνομα API δεν αλλάζει για κάθε έκδοση, επειδή αυτό θα ήταν μια ασύμβατη διακοπή API και ABI. Θεωρητικά, μπορεί να υπάρξει μια μελλοντική API gtkmm-4.0 που θα εγκαθίσταται παράλληλα με το gtkmm-3.0 χωρίς να επηρεάζει τις υπάρχουσες εφαρμογές.gtkmm_helloguintgunicharifdefπληροφορία: Ένα αναγνωριστικό που θα σταλεί στα σήματά σας για να σας πει ποια TargetEntry χρησιμοποιήθηκε.intint cols_count = m_TreeView.append_column_editable("Alex", m_columns.alex);
Gtk::TreeViewColumn* pColumn = m_TreeView.get_column(cols_count-1);
if(pColumn)
{
  Gtk::CellRendererToggle* pRenderer =
    static_cast&lt;Gtk::CellRendererToggle*&gt;(pColumn-&gt;get_first_cell());
  pColumn-&gt;add_attribute(pRenderer-&gt;property_visible(), m_columns.visible);
  pColumn-&gt;add_attribute(pRenderer-&gt;property_activatable(), m_columns.world);int main(int argc, char** argv)
{
  Glib::RefPtr&lt;Gtk::Application&gt; app = Gtk::Application::create(argc, argv, "org.gtkmm.example");

  HelloWorld helloworld;
  return app-&gt;run(helloworld);
}intltool-update --potαποχώρησηlib_LTLIBRARIESlibsigc++ 2.0Μετατροπές m4Αρχικοποιήσεις m4m_TextView.add_child_at_anchor(m_Button, refAnchor);m_TreeView.append_column("Messages", m_Columns.m_col_text);m_TreeView.set_model(m_refListStore);m_box.pack_start(m_Button1);
m_box.pack_start(m_Button2);m_button1.signal_clicked().connect( sigc::mem_fun(*this,
  &amp;HelloWorld::on_button_clicked) );m_combo.set_entry_text_column(m_columns.m_col_name);m_combo.signal_changed().connect( sigc::mem_fun(*this,
      &amp;ExampleWindow::on_combo_changed) );m_frame.add(m_box);m_rb2.set_group(m_rb1.get_group()); //δεν δουλεύειm_refActionGroup = Gtk::ActionGroup::create();

m_refActionGroup-&gt;add( Gtk::Action::create("MenuFile", "_File") );
m_refActionGroup-&gt;add( Gtk::Action::create("New", "_New"),
  sigc::mem_fun(*this, &amp;ExampleWindow::on_action_file_new) );
m_refActionGroup-&gt;add( Gtk::Action::create("ExportData", "Export Data"),
  sigc::mem_fun(*this, &amp;ExampleWindow::on_action_file_open) );
m_refActionGroup-&gt;add( Gtk::Action::create("Quit", "_Quit"),
  sigc::mem_fun(*this, &amp;ExampleWindow::on_action_file_quit) );m_refTreeSelection-&gt;set_select_function( sigc::mem_fun(*this,
    &amp;DemoWindow::select_function) );modules = [ 'gtkmm' ]moduleset = 'gnome-suites-core-deps-3.12'χωρίς προεπιλεγμένο χειριστή (no_default_handler)Χωρίς αντιγραφή υποδοχής (no_slot_copy)αντικείμενα (GObjects, γραφικά συστατικά, διεπαφές, απλές δομές και δομές τύπου πλαισίου)ήpangommpkg-configπατημένοιδιότητεςrefBuffer-&gt;apply_tag(refTagMatch, iterRangeStart, iterRangeStop);refBuffer-&gt;insert_with_tag(iter, "Some text", refTagMatch);refClipboard-&gt;request_contents("example_custom_target",
    sigc::mem_fun(*this, &amp;ExampleWindow::on_clipboard_received) );refClipboard-&gt;request_targets( sigc::mem_fun(*this,
    &amp;ExampleWindow::on_clipboard_received_targets) )·refTreeSelection-&gt;selected_foreach_iter(
    sigc::mem_fun(*this, &amp;TheClass::selected_row_callback) );

void TheClass::selected_row_callback(
    const Gtk::TreeModel::iterator&amp; iter)
{
  TreeModel::Row row = *iter;
  //Do something with the row.
}refTreeSelection-&gt;set_mode(Gtk::SELECTION_MULTIPLE);refTreeSelection-&gt;signal_changed().connect(
    sigc::mem_fun(*this, &amp;Example_IconTheme::on_selection_changed)
);επιστροφή αναφοράς (refreturn)επιστροφή αναφοράς τύπου c (refreturn_ctype)ελευθερωμένοreturn app-&gt;run(window);row[m_Columns.m_col_text] = "sometext";σήματαυποδοχή επανάκλησης (slot_callback)όνομα υποδοχής (slot_name)src/main.cc
src/other.ccstd::cout &lt;&lt; Glib::ustring::compose(
             _("Current amount: %1 Future: %2"), amount, future) &lt;&lt; std::endl;

label.set_text(Glib::ustring::compose(_("Really delete %1 now?"), filename));std::cout &lt;&lt; _("Current amount: ") &lt;&lt; amount
          &lt;&lt; _(" Future: ") &lt;&lt; future &lt;&lt; std::endl;

label.set_text(_("Really delete ") + filename + _(" now?"));std::ostringstream output·
output.imbue(std::locale(""))· // χρήση των τοπικών ρυθμίσεων χρήστη για αυτήν τη ροή
output &lt;&lt; percentage &lt;&lt; " % done"·
label-&gt;set_text(Glib::locale_to_utf8(output.str()))·std::stringΤο std::string χρησιμοποιεί 8 δυαδικά ψηφία ανά χαρακτήρα, αλλά 8 δυαδικά δεν είναι αρκετά για κωδικοποίηση γλωσσών όπως αραβικά, κινέζικα και ιαπωνικά. Αν και οι κωδικοποιήσεις για αυτές τις γλώσσες έχουν τώρα καθοριστεί από την κοινοπραξία Unicode, οι γλώσσες C και C++ δεν παρέχουν ακόμα καμιά προτυποποιημένη υποστήριξη Unicode. GTK+ και GNOME επιλέγουν την υλοποίηση του Unicode χρησιμοποιώντας UTF-8 και αυτό συσκευάζεται από το Glib::ustring. Παρέχει σχεδόν ακριβώς την ίδια διεπαφή ως std::string, μαζί με αυτόματες μετατροπές προς και από std::string.std::vector&lt; Glib::RefPtr&lt;Gtk::RecentInfo&gt; &gt; info_list = recent_manager-&gt;get_items();προορισμός: Ένα όνομα, όπως "ΣΥΜΒΟΛΟΣΕΙΡΑ"Ελληνική μεταφραστική ομάδα του GNOME
 Δημήτρης Σπίγγος <dmtrs32@gmail.com>, 2013
Για περισσότερα δείτε: http://gnome.grtypedef Gtk::TreeModel::Children type_children; //minimise code length.
type_children children = refModel-&gt;children();
for(type_children::iterator iter = children.begin();
    iter != children.end(); ++iter)
{
  Gtk::TreeModel::Row row = *iter;
  //Do something with the row - see above for set/get.
}vfuncsvfuncs (πεδία μέλους δείκτη συνάρτησης σε δομές), γραμμένα με το χέρι.void ExampleWindow::on_button_delete()
{
  Glib::RefPtr&lt;Gtk::TreeSelection&gt; refTreeSelection =
      m_treeview.get_selection();
  if(refTreeSelection)
  {
    Gtk::TreeModel::iterator sorted_iter =
        m_refTreeSelection-&gt;get_selected();
    if(sorted_iter)
    {
      Gtk::TreeModel::iterator iter =
          m_refModelSort-&gt;convert_iter_to_child_iter(sorted_iter);
      m_refModel-&gt;erase(iter);
    }
  }
}void ExampleWindow::on_clipboard_get(
    Gtk::SelectionData&amp; selection_data, guint /* info */)
{
  const std::string target = selection_data.get_target();

  if(target == "example_custom_target")
    selection_data.set("example_custom_target", m_ClipboardStore);
}void ExampleWindow::on_clipboard_received(
    const Gtk::SelectionData&amp; selection_data)
{
  Glib::ustring clipboard_data = selection_data.get_data_as_string();
  //Do something with the pasted data.
}void ExampleWindow::on_clipboard_received_targets(
  const std::vector&lt;Glib::ustring&gt;&amp; targets)
{
  const bool bPasteIsPossible =
    std::find(targets.begin(), targets.end(),
      example_target_custom) != targets.end();

  // Ενεργοποίηση/απενεργοποίηση του κατάλληλου κουμπιού επικόλλησης:
  m_Button_Paste.set_sensitive(bPasteIsPossible);
}void cb_rotate_picture (MyPicture* picture)
{
  picture-&gt;set_rotation(adj-&gt;get_value());
...void doSomething(const Cairo::RefPtr&lt;Cairo::Context&gt;&amp; context, int x)
{
    context-&gt;save();
    // αλλαγή κατάστασης γραφικών
    // εκτέλεση λειτουργιών σχεδίασης
    context-&gt;restore();
}void drag_dest_set(const std::vector&lt;Gtk::TargetEntry&gt;&amp; targets,
    Gtk::DestDefaults flags, Gdk::DragAction actions);void drag_source_set(const std::vector&lt;Gtk::TargetEntry&gt;&amp; targets,
      Gdk::ModifierType start_button_mask, Gdk::DragAction actions);void pack_start(Gtk::Widget&amp; child,
                Gtk::PackOptions options = Gtk::PACK_EXPAND_WIDGET,
                guint padding = 0);όπου η <parameter>condition</parameter> ορίζεται όπως παραπάνω. Ως συνήθως, η υποδοχή δημιουργείται με την <function>sigc::mem_fun()</function> (για μια μέθοδο μέλους ενός αντικειμένου.), ή <function>sigc::ptr_fun()</function> (για μια συνάρτηση).wrap_init_flagsxgettext -a -o my-strings --omit-header *.cc *.h