bas*_*ibe 30 wpf comparison cocoa qt programming-languages
我用Qt完成了几个月的开发(仅以编程方式构建GUI),现在我开始使用Cocoa了.我不得不说,我喜欢可可.使用Cocoa,很多Qt中看起来很难的东西都很容易.Obj-C似乎远不如C++复杂.
这可能只是我,所以:你觉得这个吗?
Cocoa如何与WPF(是正确的框架?)相比?
Obj-C与C#与C++相比如何?
XCode/Interface Builder如何将Visual Studio与Qt Creator进行比较?
Documentations如何比较?
例如,我发现Cocoa的Outlets/Actions比Qt的Signals and Slots更有用,因为它们实际上似乎涵盖了大多数GUI交互,而我不得不在一半时间内处理Signals/Slots.(我只是错误地使用它们吗?)
另外,XCode的标准模板给我复制/粘贴,撤消/重做,保存/打开以及许多其他东西几乎是免费的,而这些是Qt中相当复杂的任务.
如果您对这些开发环境/框架/语言中至少有两个有实际了解,请回答.
Ray*_*rns 78
多年来,我一直与Cocoa/Obj-C合作.截至2010年,我发现与WPF/NET Framework相比,它非常有限.我将列出我发现的一些差异,你可以自己判断.
标记语言
当我在WPF中设计时,我得到的标记是非常简单的XML,我可以使用我自己编写的工具轻松地手工编辑或编辑.在Cocoa中,我必须使用xib文件,这些文件不是为简单的手工编辑或操作而设计的.这是WPF标记的一个简单示例:
<DockPanel>
<Label>Select your favorite food:</Label>
<ComboBox
SelectedText="{Binding FavoriteFood}"
SelectedItemsSource="{Binding AllFoods}" />
</DockPanel>
Run Code Online (Sandbox Code Playgroud)
这是整个标记,相当于大约50行难以编辑的.xib.
查看和编辑简单XAML的能力非常有价值:
布局功能
In WPF I can use panels to automatically lay out my controls as the window size changes. I can use styles to define the spacing between my controls, or I can adjust margins to get the precise look I want, or both. In either case my UI will automatically adjust to changes in font sizes, window size, and screen resolution. In Cocoa, all controls are at specific x and y locations as with WinForms and the only thing I can do is auto-resize. This is extremely limiting. For example:
WPF布局的优点是您可以通过向面板添加控件的方式表达您的意图,然后稍后调整精确的布局.请注意,WPF也可以采用老式的方式,但是一旦你使用面板进行布局,你将永远不会回到X/Y布局.
例如,我所做的一个应用程序包含星级和评论框的行.通常情况下,该行只是星级的高度,但是当在文本框中键入长的通信时,TextBox变得更高,这使得行更高,因此以下行向下移动.使用WPF我可以免费获得这种行为 - 使用Cocoa,我不得不手工编写代码.
数据连接
使用Cocoa/Obj-C,您几乎只限于内置数据连接,其中包括基本数据库访问和与文件的序列化.使用WPF/.NET Framework,您可以直接将UI绑定到几乎任何阳光下的任何内容,包括:
In fact, you can bind to practically anything that has had a driver written in any NET Framework language - and there are over a hundred NET Framework languages.
Repetitive code
In Cocoa your model consists of a .h and a .m file, your controller consists of a .h and a .m file, and your view consists of a .xib file. Every single field in every object in your model must be referenced every one of these places!
In WPF/NET, a single field generally only appears in two lines of code: Once where the model is defined, and once where it is presented by the view. For example, in my code I usually define simple model fields in XML:
<Property Name="City" Type="string" />
Run Code Online (Sandbox Code Playgroud)
then to create a text box to edit the city I simply drag the "City" property into my view and end up with this XAML:
<TextBox Text="{Binding City}" />
Run Code Online (Sandbox Code Playgroud)
So "City" is mentioned in only two lines of code in my entire application (unless I have another "City" text box elsewhere). In Cocoa "City" will be referenced at least five times.
Binding directly to the model
In Cocoa a single controller is really only suitable for a single view: If you create a new view for the same model you need a new controller. In WPF/NET there is a better way to do it, though you can still create controllers if you really want to.
In WPF/NET a view will typically bind most of its controls directly to the model (see my City example above). Other controls will be bound to a "View Model" that models the state information associated with the current view. For example, if you are searching the "View Model" would contain the search string so it can be used by the view both to filter the results and to hilight the search text.
In WPF/NET you can also bind multiple properties of a control to the same or different parts of your model (or view model):
<TextBox Text="{Binding AmountToTransfer}"
Background="{edf:Binding UserIsHappy ? Green : White}" />
Run Code Online (Sandbox Code Playgroud)
The difference is that in WPF a view model is usually shareable between several screens that are similar in their behavior, so in a LOB application when you create a custom view all you need to do is edit a single file.
Command architecture
In Cocoa a button stores its target and action in a NSActionCell within the view, which means that it will invoke a specific method on a specific object (typically the controller). In WPF/NET a button has a Click event that works the same way, but it also has a Command property that allows you to invoke a command.
Commands in WPF are very powerful, since a single Command may be shared throughout the application. For example, WPF itself defines a Delete command. As long as your model responds to this command, adding a "Delete" button to your view is as simple as selecting the Delete command in the properties window, which creates this XAML:
<Button Command="Delete" />
Run Code Online (Sandbox Code Playgroud)
This is all you have to do to get a functional delete button that deletes the object from a list. Note the built-in Delete command also:
A command is routed to ancestor objects and models, so in a typical application you almost never need to specify which object receives the command.
Style sheets
In Cocoa there is no mechanism to apply style sheets to panels and have them affect all the controls in the panel, either at design time or at run time. For example an application may want to:
WPF/NET makes all of these operations trivial through the use of styles. You can set any property of any object through a style. Styles can be set implicitly by object type or explicitly, for example:
<Button Style="{StaticResource DeleteButtonStyle}" />
Run Code Online (Sandbox Code Playgroud)
Style sheets can be defined anywhere you like: in a control libraries, at the application level, specific to a "theme", on a window, in a specific control's resource dicitionary, or directly on a control.
Control templates
In Cocoa you cannot do much to change the visual styling of controls except to subclass them, since they each draw their own appearance. In WPF/NET the appearance of a control is given by its template which can be freely replaced with pretty much anything you can think of.
For example:
Control templates and data templates may also include built-in animations, so for example your door can actually animate swinging open and closed when you click on it. This is trivially simple to do in Expression Blend: It takes about 20 clicks of the mouse. Just create two linear animations and attach them to event triggers.
Custom controls
Cocoa and WPF both allow you to subclass existing controls to create new ones. In Cocoa the new controls are serialized to the .xib/.nib file. In WPF they are part of the XAML just like the built-in controls:
<StackPanel>
<TextBlock>
Hello, <Run Text="{Binding FirstName}" />.
<Bold>Good morning!</Bold> How are you today?
</TextBlock>
<my:JoySelector Happiness="{Binding Happiness}" />
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
In this example JoySelector would be a control I defined and Happiness would be one of its properties.
A big difference between Cocoa and WPF is in the drawing of the custom controls. In Cocoa you must code calls to drawing primitives to create your control's appearance. While this is an option in WPF, it is usually much more easily done using a control template.
For example, in Cocoa you might write:
CGSize size = CGSizeMake(30, 20);
UIGraphicsBeginImageContext(size);
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetRGBFillColor(context, 1.0, 1.0, 0.0, 0.0);
CGContextFillEllipseInRect(context, rect);
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return image;
Run Code Online (Sandbox Code Playgroud)
whereas in WPF using XAML the equivalent would be:
<Ellipse Width="30" Height="20" Fill="Red" />
Run Code Online (Sandbox Code Playgroud)
or in WPF in code (C#):
return new Ellipse { Width=30, Height=30, Fill=Brushes.Red };
Run Code Online (Sandbox Code Playgroud)
A ControlTemplate may of course have multiple items:
<ControlTemplate TargetType="my:JoySelector">
<Grid Width="50" Height="50">
<Ellipse Width="30" Height="20" Fill="Red" VerticalAlignment="Left" />
<Path Data="M0,0 L3,5 L8,8 L5,3 L0,0" Fill="Blue" />
<ComboBox
SelectedItem="{TemplateBinding Happiness}"
Style="{StaticResource JoySelectorBoxStyle}" />
</Grid>
</ControlTemplate>
Run Code Online (Sandbox Code Playgroud)
This XAML would typically be created in Expression Blend by right-clicking a JoySelector, selecting Edit > Template > Create New, drawing the Ellipse, Path, and ComboBox using the drawing tools, and selecting the ComboBox binding and style from the Properties window.
Data templates
In Cocoa if you want a list or tree of items of various types, such as an equipment inventory in a game or a list of various types of accounts (investment, money market, savings), you pretty much have to code it all yourself. In WPF/NET you can use DataTemplates.
For example, if every weapon has a "hit strength" and a "defense strength" you might include a data template like this:
<DataTemplate TargetType="game:Weapon">
<DockPanel TextElement.FontWeight="Bold">
<Image Source="{StaticResource WeaponDrawing}" />
<TextBlock Text="{Binding WeaponName}" DockPanel.Dock="Top" />
<TextBlock Text="{Binding HitStrength}" Foreground="Red" />
<TextBlock Text="{Binidng DefenseStrength}" Foreground="Blue" />
</DockPanel>
</DataTemplate>
Run Code Online (Sandbox Code Playgroud)
Other game objects would use different templates, then the inventory could be displayed using a ListBox using a WrapPanel to lay them out in reading order. (Note that in WPF, a ListBox doesn't have to present its items in a vertical list: Any panel can be used.)
This same technique is important in LOB applications: For example, you can have a default representation for an Invoice that is set in an application-wide DataTemplate, so any part of your application that presents lists of Invoices will automatically display them in the default format. This might include an icon, the invoice number, a tooltip popup with additional information, and a context menu that allows the invoice to be opened and/or edited.
Triggers and animations
In Cocoa you can do animations, but must write code both to create the animation and to apply the animation. In WPF you can define the animation using a timeline in Expression Blend, and set EventTriggers and PropertyTriggers in the view to control when it runs. To create an animation that shakes a button, just right-click to create a timeline, set the button's position, rotation or scale using the mouse at a few points on the time line, and change the automatically-created EventTrigger to the event you want to trigger the button.
Cocoa has no animation property store or coercion mechanism, so any changes made by the animation are permanent: You can't remove the animation and have the property values revert. Also you cannot animate properties of shared resources (such as brush colors) without manually copying them, and you can't animate to out-of-range values and have the control itself coerce to the appropriate value. In WPF the animation system has the ability to keep track of animation values, bound values, default values and coerced values separately so you don't run into these problems.
In WPF you can set animations to run on UI events like button clicks, property state changes (including data changes in the model), events generated by the model, to run continuously, or via code.
In WPF you can create custom animation classes and use these with Expression Blend as if they were part of WPF. You can also draw the Geometry objects used by the built-in PathAnimation rather than coding it yourself.
Note that WPF has the ability to construct and start animations in code if you really want to. Also note that embedding an animation from a separate application such as Quartz Composer, is not the same thing as animating properties of UI objects. Both Cocoa and WPF can embed animations created with other technologies but with WPF you can use Expression Blend to create a timeline that animates any part of your UI.
Conversions as part of binding
Cocoa has the ability to do conversions to and from from a single value using a NSFormatter. Anything more complicated must be done in the controller. In WPF you can use a StringFormat for the simple cases Cocoa's built-in NSFormatters cover, but you can also specify an IValueConverter or IMultiValueConverter to implement custom conversion of values. For example, you can add a custom converter to a bar chart data series to cause the data items in the bar chart to animate to their target values in rapid sequence (known as a "jelly" animation). WPF's converters can be used one-way or two-way and can convert a single value or multiple values.
Conversions also allow you to bind to multiple properties or calculations and to format the result, for example:
<TextBlock Text="{edf:Binding (Height + Width)/2, StringFormat=0.000}" />
Run Code Online (Sandbox Code Playgroud)
This sort of binding with conversion is not possible in Cocoa.
Third party controls
In Cocoa you can generally only include UI widgets designed for Cocoa in your application. In WPF you can include WPF controls but you can also include sections of your UI developed using WinForms, MFC, HTML, Java, Flash, and other technologies. WPF provides facilities for integrating these other technologies directly into WPF, even to the extent of using its markup system to construct the objects and set their properties, for example:
<StackPanel>
<TextBlock>Here is a WinForms control:</TextBlock>
<WindowsFormsHost>
<tools:LegacyChartingControl
Width="20" Height="30"
Title="Graph of something"
SeriesXMin="0"
SeriesXMax="10" ... />
</WindowsFormsHost>
</StackPanel>
Run Code Online (Sandbox Code Playgroud)
Externally-created media
Both Cocoa and WPF can include media such as videos, animations, and bitmaps that have been created in third-party tools. Each environment supports all such media types supported by the underlying operating system. WPF provides a bit more than Cocoa in terms of controlling the media, for example you if you set a button's command to "MediaCommands.NextTrack" or "MediaCommands.FastForward", the media will automatically respond appropriately. Also, WPF provides some improvements in the asynchronous loading of media.
WPF (through Silverlight) also supports several high quality video and audio codecs in a fully cross-platform manner so you can rely on your media working on any platform.
There are also tools that allow you to convert drawings created in tools like Illustrator or animations created in tools like Flash into native WPF drawings and animations, allowing you to manipulate and data-bind their properties. For example, you could take a bouncing ball animation created in Flash and data-bind its Y coordinate at apogee so that the ball bounces higher or lower based on the data value in your model.
Garbage collection
As of 2007 garbage collection is finally supported in Cocoa/Obj-C, but many libraries still can't handle it so most of the Cocoa code being written today is still using manual memory allocation with reference counting. Thus even today you still a lot of "[abc release]" sprinkled throughout Cocoa code! WPF/NET has had garbage collection from day one, so it does not have this problem.
Execution within web browser
Cocoa applications are currently limited to executing as desktop applications, whereas WPF can run just as easily within the web browser as on the desktop, using either XBAP or Silverlight technology.
Cross-platform capability
The story here is similar:
Cocoa applications run natively on Mac OS X, and can also run on Windows and Linux by using Cocotron or GNUstep and restricting yourself to a subset of the features.
WPF applications run natively on Windows, and can also run on Mac OS X and Linux by using Silverlight and restricting yourself to a subset of the features.
The only significant difference is that Silverlight can run in the browser and has much better vendor support and tooling than Cocotron or GNUstep.
Other advanced capabilities of WPF
So far I have not found any capability in Cocoa that is not also in WPF/NET, but I have found many in WPF/NET that are not in Cocoa, for example:
Third party algorithms and drivers
Cocoa/Obj-C can call pre-compiled libraries that use C calling conventions and call invoke methods on objects defined in certain other languages. This means that a C-style API is generally required for third-party code that needs to be integrated into your application. WPF/NET can include code written in over 100 languages directly into your application and allows you to access all functionality directly. In addition, it can also call into precompiled code written in other languages using C, C++, COM, DCOM, Web Services, and other calling conventions. In addition, there are open-source shims allowing NET Framework code to call directly into a wide variety of other languages and systems. This means that WPF applications almost never have to include more than a tiny amount of glue code to connect to third party code, including device drivers.
Language comparison
Comparing Objective-C with C# is a major task, and one I will not attempt. Suffice it to say that as of version 4.0, C# contains all the features on Objective-C and many, many, many more. I learned Objective-C in 1989 - a long time before C# was even conceived of - and at the time it was an amazingly powerful language. Now when I use it I cringe, especially at the loss of LINQ and Generics.
Try this sort of data transformation in Objective-C:
DataContext =
from lesson in AllLessons
where lesson.Active
groupby lesson.Category into category
select new
{
categoryName = category.Key.Name,
lessonsInCategory =
from lesson in category
select new
{
lesson,
fullName = lesson.ShortName + " " + lesson.Suffix,
priority = rand.Next(10)
}
};
Run Code Online (Sandbox Code Playgroud)
If AllLessons is provided dynamically, you can directly bind this result in WPF (with <ListBox ItemsSource="{Binding}" />) and have it dynamically update in real time.
When using LINQ with C# you can also do joins, sorting, etc. There is no back-end code to write at all, and Visual Studio's IntelliSense helps you complete the names of properties, etc as you edit and even underlines your mistakes.
I don't know of any good comparison between Objective-C and C#, but there is a good comparison between C# and Java on wikipedia that calls out many of C#'s features that are also missing from Objective-C.
Language bindings
Cocoa is not restricted to Objective-C, and WPF is not restricted to C#. Both are accessible from a number of other languages. The difference
| 归档时间: |
|
| 查看次数: |
15121 次 |
| 最近记录: |