Gtk 滚动绘图区域
仅供参考:我使用Ada作为编程语言,窗口软件是Gtk和GtkAda 我有一个绘图区域,有时不适合我的窗口,即使我使用全屏。因此,我需要有一个滚动区域。我使用附带的代码获得这样一个窗口,但滚动条始终无法移动,因此无法看到我的图形的一部分。我必须向程序中添加什么,以及在运行程序中必须更改滚动条的范围时我必须做什么Gtk 滚动绘图区域,gtk,scrollbar,viewport,ada,drawingarea,Gtk,Scrollbar,Viewport,Ada,Drawingarea,仅供参考:我使用Ada作为编程语言,窗口软件是Gtk和GtkAda 我有一个绘图区域,有时不适合我的窗口,即使我使用全屏。因此,我需要有一个滚动区域。我使用附带的代码获得这样一个窗口,但滚动条始终无法移动,因此无法看到我的图形的一部分。我必须向程序中添加什么,以及在运行程序中必须更改滚动条的范围时我必须做什么 Gtk_New (MainWindow.Scrolledwindow); Set_Policy (MainWindow.Scrolledwindow, Policy_Alw
Gtk_New (MainWindow.Scrolledwindow);
Set_Policy (MainWindow.Scrolledwindow, Policy_Always, Policy_Always);
Set_Shadow_Type (MainWindow.Scrolledwindow, Shadow_None);
Set_Placement (MainWindow.Scrolledwindow, Corner_Top_Left);
Gtk_New (MainWindow.View_Port);
Gtk_New (MainWindow.DrawingArea);
MainWindow.Scrolledwindow.Add(MainWindow.View_Port);
MainWindow.View_Port.Add(MainWindow.DrawingArea);
Pack_Start
(MainWindow.Main_Box1,
MainWindow.Scrolledwindow,
Expand => True,
Fill => True,
Padding => 0);
我认为您可以省略ViewPort小部件,只使用一个框来替换它。如@lb90所述,您可以使用
set\u size\u Request
设置绘图区域的大小。这似乎起到了作用:
main.adb
with Gtk.Main;
with Demo.Main_Window;
procedure Main is
use Demo.Main_Window;
Main_Window : Demo_Main_Window;
begin
Gtk.Main.Init;
Gtk_New (Main_Window);
Gtk.Main.Main;
end Main;
with Glib; use Glib;
with Gtk.Main;
with Gtk.Widget;
with Gtk.Window;
with Gtk.Enums;
with Gtk.Adjustment;
with Cairo;
package body Demo.Main_Window is
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
function Draw_Event_Callback
(Self : access Gtk.Widget.Gtk_Widget_Record'Class;
Cr : Cairo.Cairo_Context) return Boolean;
-------------
-- Gtk_New --
-------------
procedure Gtk_New (Main_Window : out Demo_Main_Window) is
begin
Main_Window := new Demo_Main_Window_Record;
Demo.Main_Window.Initialize (Main_Window);
end Gtk_New;
----------------
-- Initialize --
----------------
procedure Initialize
(Main_Window : not null access Demo_Main_Window_Record'Class)
is
begin
Gtk.Window.Initialize (Main_Window);
-- Setup window
Main_Window.Set_Title ("Demo");
Main_Window.Set_Size_Request (Window_Width, Window_Height);
Main_Window.Set_Resizable (False);
Main_Window.On_Destroy (Destroy_Event_Callback'Access);
-- Add controls
Gtk_New (Main_Window.SW);
Gtk_New_Vbox (Main_Window.VB);
Gtk_New (Main_Window.DA);
Main_Window.SW.Set_Policy
(Hscrollbar_Policy => Gtk.Enums.Policy_Always,
Vscrollbar_Policy => Gtk.Enums.Policy_Always);
Main_Window.DA.Set_Size_Request (Draw_Area_Width, Draw_Area_Height);
Main_Window.DA.On_Draw (Draw_Event_Callback'Access);
Main_Window.VB.Pack_Start (Main_Window.DA, True, True, 0);
Main_Window.SW.Add (Main_Window.VB);
Main_Window.Add (Main_Window.SW);
-- Show the window.
Main_Window.Show_All;
end Initialize;
----------------------------
-- Destroy_Event_Callback --
----------------------------
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
is
begin
Gtk.Main.Main_Quit;
end Destroy_Event_Callback;
-------------------------
-- Draw_Event_Callback --
-------------------------
function Draw_Event_Callback
(Self : access Gtk.Widget.Gtk_Widget_Record'Class;
Cr : Cairo.Cairo_Context) return Boolean
is
-- Draw some rectangles. This function is not optimal in terms of
-- performance as everything is being redrawn, including the non
-- visible parts, but it's OK (I think) for the demo.
Num_X : constant Gint := 20;
Num_Y : constant Gint := 20;
Ratio : constant Gdouble := 0.8;
Dx : constant GDouble := GDouble (Self.Get_Allocated_Width / Num_X);
Dy : constant GDouble := GDouble (Self.Get_Allocated_Height / Num_Y);
-- Or, alternatively (same outcome)
-- Dx : constant GDouble := GDouble (Draw_Area_Width / Num_X);
-- Dy : constant GDouble := GDouble (Draw_Area_Height / Num_Y);
begin
for X in 0 .. Num_X - 1 loop
for Y in 0 .. Num_Y - 1 loop
Cairo.Set_Source_RGB
(Cr => Cr,
Red => GDouble (X) / GDouble (Num_X),
Green => GDouble (X * Y) / GDouble (Num_X * Num_Y),
Blue => GDouble (Y) / GDouble (Num_Y));
Cairo.Rectangle
(Cr => Cr,
X => Dx * (GDouble (X) + 0.5 * (1.0 - Ratio)),
Y => Dy * (GDouble (Y) + 0.5 * (1.0 - Ratio)),
Width => Dx * Ratio,
Height => Dy * Ratio);
Cairo.Fill (Cr);
end loop;
end loop;
return True; -- GDK_EVENT_STOP, do not propagate event to parent.
end Draw_Event_Callback;
end Demo.Main_Window;
demo.ads
package Demo is
end Demo;
with Glib; use Glib;
with Gtk.Window;
with Gtk.Scrolled_Window;
with Gtk.Box;
with Gtk.Drawing_Area;
package Demo.Main_Window is
type Demo_Main_Window_Record is new Gtk.Window.Gtk_Window_Record with private;
type Demo_Main_Window is access all Demo_Main_Window_Record'Class;
------------------
-- Constructors --
------------------
procedure Gtk_New
(Main_Window : out Demo_Main_Window);
procedure Initialize
(Main_Window : not null access Demo_Main_Window_Record'Class);
private
use Gtk.Scrolled_Window;
use Gtk.Box;
use Gtk.Drawing_Area;
Window_Width : constant Gint := 640;
Window_Height : constant Gint := 480;
Draw_Area_Width : constant Gint := 1000;
Draw_Area_Height : constant Gint := 1000;
type Demo_Main_Window_Record is
new Gtk.Window.Gtk_Window_Record with
record
SW : Gtk_Scrolled_Window;
VB : Gtk_Vbox;
DA : Gtk_Drawing_Area;
end record;
end Demo.Main_Window;
demo-main\u窗口广告
package Demo is
end Demo;
with Glib; use Glib;
with Gtk.Window;
with Gtk.Scrolled_Window;
with Gtk.Box;
with Gtk.Drawing_Area;
package Demo.Main_Window is
type Demo_Main_Window_Record is new Gtk.Window.Gtk_Window_Record with private;
type Demo_Main_Window is access all Demo_Main_Window_Record'Class;
------------------
-- Constructors --
------------------
procedure Gtk_New
(Main_Window : out Demo_Main_Window);
procedure Initialize
(Main_Window : not null access Demo_Main_Window_Record'Class);
private
use Gtk.Scrolled_Window;
use Gtk.Box;
use Gtk.Drawing_Area;
Window_Width : constant Gint := 640;
Window_Height : constant Gint := 480;
Draw_Area_Width : constant Gint := 1000;
Draw_Area_Height : constant Gint := 1000;
type Demo_Main_Window_Record is
new Gtk.Window.Gtk_Window_Record with
record
SW : Gtk_Scrolled_Window;
VB : Gtk_Vbox;
DA : Gtk_Drawing_Area;
end record;
end Demo.Main_Window;
演示主窗口。adb
with Gtk.Main;
with Demo.Main_Window;
procedure Main is
use Demo.Main_Window;
Main_Window : Demo_Main_Window;
begin
Gtk.Main.Init;
Gtk_New (Main_Window);
Gtk.Main.Main;
end Main;
with Glib; use Glib;
with Gtk.Main;
with Gtk.Widget;
with Gtk.Window;
with Gtk.Enums;
with Gtk.Adjustment;
with Cairo;
package body Demo.Main_Window is
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class);
function Draw_Event_Callback
(Self : access Gtk.Widget.Gtk_Widget_Record'Class;
Cr : Cairo.Cairo_Context) return Boolean;
-------------
-- Gtk_New --
-------------
procedure Gtk_New (Main_Window : out Demo_Main_Window) is
begin
Main_Window := new Demo_Main_Window_Record;
Demo.Main_Window.Initialize (Main_Window);
end Gtk_New;
----------------
-- Initialize --
----------------
procedure Initialize
(Main_Window : not null access Demo_Main_Window_Record'Class)
is
begin
Gtk.Window.Initialize (Main_Window);
-- Setup window
Main_Window.Set_Title ("Demo");
Main_Window.Set_Size_Request (Window_Width, Window_Height);
Main_Window.Set_Resizable (False);
Main_Window.On_Destroy (Destroy_Event_Callback'Access);
-- Add controls
Gtk_New (Main_Window.SW);
Gtk_New_Vbox (Main_Window.VB);
Gtk_New (Main_Window.DA);
Main_Window.SW.Set_Policy
(Hscrollbar_Policy => Gtk.Enums.Policy_Always,
Vscrollbar_Policy => Gtk.Enums.Policy_Always);
Main_Window.DA.Set_Size_Request (Draw_Area_Width, Draw_Area_Height);
Main_Window.DA.On_Draw (Draw_Event_Callback'Access);
Main_Window.VB.Pack_Start (Main_Window.DA, True, True, 0);
Main_Window.SW.Add (Main_Window.VB);
Main_Window.Add (Main_Window.SW);
-- Show the window.
Main_Window.Show_All;
end Initialize;
----------------------------
-- Destroy_Event_Callback --
----------------------------
procedure Destroy_Event_Callback
(Widget : access Gtk.Widget.Gtk_Widget_Record'Class)
is
begin
Gtk.Main.Main_Quit;
end Destroy_Event_Callback;
-------------------------
-- Draw_Event_Callback --
-------------------------
function Draw_Event_Callback
(Self : access Gtk.Widget.Gtk_Widget_Record'Class;
Cr : Cairo.Cairo_Context) return Boolean
is
-- Draw some rectangles. This function is not optimal in terms of
-- performance as everything is being redrawn, including the non
-- visible parts, but it's OK (I think) for the demo.
Num_X : constant Gint := 20;
Num_Y : constant Gint := 20;
Ratio : constant Gdouble := 0.8;
Dx : constant GDouble := GDouble (Self.Get_Allocated_Width / Num_X);
Dy : constant GDouble := GDouble (Self.Get_Allocated_Height / Num_Y);
-- Or, alternatively (same outcome)
-- Dx : constant GDouble := GDouble (Draw_Area_Width / Num_X);
-- Dy : constant GDouble := GDouble (Draw_Area_Height / Num_Y);
begin
for X in 0 .. Num_X - 1 loop
for Y in 0 .. Num_Y - 1 loop
Cairo.Set_Source_RGB
(Cr => Cr,
Red => GDouble (X) / GDouble (Num_X),
Green => GDouble (X * Y) / GDouble (Num_X * Num_Y),
Blue => GDouble (Y) / GDouble (Num_Y));
Cairo.Rectangle
(Cr => Cr,
X => Dx * (GDouble (X) + 0.5 * (1.0 - Ratio)),
Y => Dy * (GDouble (Y) + 0.5 * (1.0 - Ratio)),
Width => Dx * Ratio,
Height => Dy * Ratio);
Cairo.Fill (Cr);
end loop;
end loop;
return True; -- GDK_EVENT_STOP, do not propagate event to parent.
end Draw_Event_Callback;
end Demo.Main_Window;
使用
main window.drawingara.Set\u size\u Request()设置绘图区域的大小